「给未来写封信」横屏适配方案复盘暨DialogX 平板适配指南

1,550 阅读2分钟

DialogX 平板适配指南暨「给未来写封信」横屏适配方案复盘

引言

首先关于 Android App 如何进行平板适配,推进阅读文章:【Android平板适配】手机/平板二合一应用一站式适配攻略@尼特胡

其中需要注意的点在这里写出来:

1.如何使 Activity 不会因为切换横竖屏自动重启

在 AndroidManifest.xml 中的 Activity 节点增加以下配置:

<activity
    ...
    android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" />

2.如何判断是否为平板及横屏

要判断当前是否为横屏,可以使用以下办法判断:

public static boolean isTablet() {
    return (getInstance().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

当前是否是横屏可以使用以下办法判断:

private static boolean isLandscape(Activity activity) {
    if (activity != null) {
        return activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    }
    return false;
}

给未来写封信是如何进行横屏适配的

基础 UI

对于大部分界面,我们进行了评估,基于开发成本考虑没有专门的为平板方式重新设计 UI,而是采用了“兼容”方案进行适配,具体逻辑是,在竖屏时保证所有 UI 界面均可以动态的对窗口大小进行匹配,而不是“等比缩放”的方案进行显示,即,按照以下逻辑,在横屏时对 UI 进行居中适配:

image.png

基于这个方案,只需要对 UI 部分进行最大宽度限制即可,对于内容布局,我们改写了内容布局的外层 ViewGroup,使其支持设置 maxWidth 最大宽度:

/**
 * @author: Kongzue
 * @github: https://github.com/kongzue/
 * @homepage: http://kongzue.com/
 * @mail: myzcxhh@live.cn
 * @createTime: 2019/9/24 17:34
 */
public class HorizontalScreenAdapterRelativeLayout extends RelativeLayout {
    
    private int maxWidth;
    private int maxHeight;
    
    public HorizontalScreenAdapterRelativeLayout(Context context) {
        super(context);
    }
    
    public HorizontalScreenAdapterRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public HorizontalScreenAdapterRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }
    
    private void init(Context context, AttributeSet attrs) {
        maxWidth = Math.min(getDisplayWidth(),getDisplayHeight());
    }
    
    public HorizontalScreenAdapterRelativeLayout setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
        return this;
    }
    
    public HorizontalScreenAdapterRelativeLayout setMaxWidth(int maxWidth) {
        if (maxWidth > 0) this.maxWidth = maxWidth;
        return this;
    }
    
    private int preWidth = -1;
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        
        if (preWidth == -1 && widthSize != 0) {
            preWidth = widthSize;
        }
        if (maxHeight > 0) {
            heightSize = Math.min(heightSize, maxHeight);
        }
        if (maxWidth > 0) {
            widthSize = Math.min(widthSize, maxWidth);
        }
        
        int maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
        int maxWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
        super.onMeasure(maxWidthMeasureSpec, maxHeightMeasureSpec);
    }
    
    public int dip2px(float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
    
    public int getDisplayWidth() {
        Display disp =  ((Activity)getContext()).getWindowManager().getDefaultDisplay();
        Point outP = new Point();
        disp.getSize(outP);
        return outP.x;
    }
    
    public int getDisplayHeight() {
        Display disp = ((Activity)getContext()).getWindowManager().getDefaultDisplay();
        Point outP = new Point();
        disp.getSize(outP);
        return outP.y;
    }
}

此布局默认会自动根据屏幕宽高的最小值,对另一个最大边进行宽高限制,也可以修改代码进行自定义。

对话框 UI

image.png

除此之外,对话框的适配也很重要,给未来写封信在对话框的 UI 上是基于 DialogX 进行开发的,而 DialogX 是自带 maxWidth 限定功能的,可以直接使用:

int maxWidth = Math.min(getDisplayWidth(), getDisplayHeight());
DialogX.dialogMaxWidth = maxWidth;

结语

以上,再次感谢小米 MIUI 团队在 Pad 适配上给与的帮助和技术支持,「给未来写封信」开发组也将继续努力提供更优质的用户体验,愿你我未来可期!