美文网首页
自定义View尺寸进行适配

自定义View尺寸进行适配

作者: 石器时代小古董 | 来源:发表于2019-05-30 00:41 被阅读0次

    一、为什么要适配

    因为Android市场的碎片化,导致APP界面再不同屏幕上显示的尺寸不一致。适配可以让布局,资源,用户流程匹配不同的屏幕。

    二、布局的适配

    1.不要写尺寸
    2.LinearLayout的权重
    3.RelativeLayout的布局方式
    4.ContraintLayout
    5.Percent-Layout来进行布局

    三、图片资源适配

    1.使用.9的图片

    2.使用SVG实现缩放

    3.使用多种尺寸的mipmap资源

    四、用户流程适配

    1.手机和平板不同的流程

    五、限定符的适配

    1.分辨率限定符 drawable-hdpi drawable-xdpi
    2.尺寸限定符layout-small,layout-large
    3.最小宽度的限定符values-sw ...
    屏幕方向的限定符layout-land,layout-port

    六、刘海屏的适配

    根据各个厂商的官方文档适配

    七、自定义View的适配

    根据设计稿获取到缩放比例,在 View Measure的时候更改View的尺寸

    缩放比例 = 使用设备尺寸 / 设计尺寸

    获取缩放尺寸的工具类

    import android.content.Context;
    import android.util.DisplayMetrics;
    import android.view.WindowManager;
    
    import java.lang.reflect.Field;
    
    public class UIUtils {
        //    工具类
        private static UIUtils instance;
        //    参考设备的宽和高 用来计算缩放比例
        public static final float STANDARD_WIDTH = 1080f;
        public static final float STANDARD_HEIGHT = 1920f;
    
        //实际设备信息  赋值    他是不知道横竖  1080  1920
        public static float displayMetricsWidth;
        public static float displayMetricsHeight;
        // 状态栏的宽高
        public static float systemBarHeight;
    
        //    applicaiton
        public static UIUtils getInstance(Context context) {
            if (instance == null) {
                instance = new UIUtils(context);
            }
            return instance;
        }
    
        public static UIUtils notityInstance(Context context) {
            instance = new UIUtils(context);
            return instance;
        }
    
        //    activity
        public static UIUtils getInstance() {
            if (instance == null) {
                throw new RuntimeException("UiUtil应该先调用含有构造方法进行初始化");
            }
            return instance;
        }
    
        private UIUtils(Context context) {
            // 获取设备的宽高
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics displayMetrics = new DisplayMetrics();
            // 获取到屏幕的宽高
            if (displayMetricsWidth == 0.0f || displayMetricsHeight == 0.0f) {
                //在这里得到设备的真实值
                windowManager.getDefaultDisplay().getMetrics(displayMetrics);
                systemBarHeight = getSystemBarHeight(context);
                //横屏
                if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
                    this.displayMetricsWidth = (float) (displayMetrics.heightPixels);
                    this.displayMetricsHeight = (float) (displayMetrics.widthPixels - systemBarHeight);
                } else {
                    //                竖屏
                    this.displayMetricsWidth = (float) (displayMetrics.widthPixels);
                    this.displayMetricsHeight = (float) (displayMetrics.heightPixels - systemBarHeight);
                }
                //            状态栏
            }
        }
    
        //
        public float getHorizontalScaleValue() {
            return ((float) (displayMetricsWidth)) / STANDARD_WIDTH;
        }
    
        public float getVerticalScaleValue() {
            return ((float) (displayMetricsHeight)) / (STANDARD_HEIGHT - systemBarHeight);
        }
    
        private int getSystemBarHeight(Context context) {
            return getValue(context, "com.android.internal.R$dimen", "system_bar_height", 48);
        }
    
        public int getWidth(int width) {
            return Math.round((float) width * this.displayMetricsWidth / STANDARD_WIDTH);
        }
    
        public int getHeight(int height) {
            return Math.round((float) height * this.displayMetricsHeight / (STANDARD_HEIGHT - systemBarHeight));
        }
    
        private int getValue(Context context, String dimeClass, String system_bar_height, int defaultValue) {
            //        com.android.internal.R$dimen    system_bar_height   状态栏的高度
            try {
                Class<?> clz = Class.forName(dimeClass);
                Object object = clz.newInstance();
                Field field = clz.getField(system_bar_height);
                int id = Integer.parseInt(field.get(object).toString());
                return context.getResources().getDimensionPixelSize(id);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return defaultValue;
        }
    
    }
    
    

    重写容器View,让容器View中的控件都被缩放

     @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (flag) {
                flag = false;
                // 获取水平和数值方向的缩放比例
                float scaleX = UIUtils.getInstance(getContext()).getHorizontalScaleValue();
                float scaleY = UIUtils.getInstance(getContext()).getVerticalScaleValue();
                int childCount = this.getChildCount();
                // 缩放所有子控件
                for (int i = 0; i < childCount; i++) {
                    View child = this.getChildAt(i);
                    LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
                    layoutParams.width = (int) (layoutParams.width * scaleX);
                    layoutParams.height = (int) (layoutParams.height * scaleY);
                    layoutParams.leftMargin = (int) (layoutParams.leftMargin * scaleX);
                    layoutParams.rightMargin = (int) (layoutParams.rightMargin * scaleX);
                    layoutParams.topMargin = (int) (layoutParams.topMargin * scaleY);
                    layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scaleY);
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:自定义View尺寸进行适配

          本文链接:https://www.haomeiwen.com/subject/zcfqtctx.html