美文网首页
自定义像素适配

自定义像素适配

作者: 面熟_gson | 来源:发表于2019-09-26 09:43 被阅读0次
    这里先举个栗子
    假设UI设计稿给的屏幕参考宽高比例是1080*1920
    这时候我们在720*1280的手机上设置一个View的宽高我们就需要通过计算出他们之间的宽高比例  
    首先我们获取参考设备和目标设备的
    水平方向的宽缩放比例=720/1080
    垂直方向的高缩放比例=1280/1920
    假如这时候设计给的一张图假如这时候设计给的一张图的宽度是100px
    但是如果想让他在720/1080的手机上显示的效果一样,
    我们就可以用计算出的水平方向的缩放比例乘上100px就
    可以得出在720*1080的设备上实际上应该显示的宽度(720/1080*100px),
    这也就是简单的数学知识计算出来的
    
    

    接下来就是代码部分了
    这里写了一个工具类,这个工具类就是我们上面所说的比例计算 ,我们通过代码获取当前运行设备的宽高,再通过和UI设计稿计算出实际应该缩放的比例 实际开发过程中我们根据实际UI设计稿的情况修改参考宽高就行了,这里考虑到了平板设备,平板设备肯定是 宽>高 手机设备 高>宽

    public class Utils {
    
        private static Utils utils;
    
        //这里是设计稿参考宽高
        private static final float STANDARD_WIDTH = 1080;
        private static final float STANDARD_HEIGHT = 1920;
    
        //这里是屏幕显示宽高
        private int mDisplayWidth;
        private int mDisplayHeight;
    
        private Utils(Context context){
            //获取屏幕的宽高
            if(mDisplayWidth == 0 || mDisplayHeight == 0){
                WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                if (manager != null){
                    DisplayMetrics displayMetrics = new DisplayMetrics();
                    manager.getDefaultDisplay().getMetrics(displayMetrics);
                    if (displayMetrics.widthPixels > displayMetrics.heightPixels){
                        //横屏
                        mDisplayWidth = displayMetrics.heightPixels;
                        mDisplayHeight = displayMetrics.widthPixels;
                    }else{
                        mDisplayWidth = displayMetrics.widthPixels;
                        mDisplayHeight = displayMetrics.heightPixels - getStatusBarHeight(context);
                    }
                }
            }
    
        }
    
    //获取状态栏的宽高  因为屏幕高度包含状态栏,所以这里高度的获取需要减去状态栏高度
        public int getStatusBarHeight(Context context){
            int resID = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resID > 0){
                return context.getResources().getDimensionPixelSize(resID);
            }
            return 0;
        }
    
        public static Utils getInstance(Context context){
            if (utils == null){
                utils = new Utils(context.getApplicationContext());
            }
            return utils;
        }
    
        //获取水平方向的缩放比例
        public float getHorizontalScale(){
            return mDisplayWidth / STANDARD_WIDTH;
        }
    
        //获取垂直方向的缩放比例
        public float getVerticalScale(){
            return mDisplayHeight / STANDARD_HEIGHT;
        }
    
    }
    
    

    最后就是重新容器控件了
    这里我重新的是RelativeLayout 作为示例,实际开发中肯定需要重新所有的容器布局
    比如LinearLayout,FrameLayout等,直接上代码吧
    代码中通过遍历RelativeLayout中的子View,通过获取他们的宽 高 Margin的参数乘以我们工具类中计算出来的缩放比例 再重新设置给View
    这里的flag实际上就是为了防止多次测量 因为onMeasure会走多次

    public class ScreenAdapterLayout extends RelativeLayout {
    
        private boolean flag;
    
        public ScreenAdapterLayout(Context context) {
            super(context);
        }
    
        public ScreenAdapterLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ScreenAdapterLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if (!flag){
                float scaleX = Utils.getInstance(getContext()).getHorizontalScale();
                float scaleY = Utils.getInstance(getContext()).getVerticalScale();
    
                int count = getChildCount();
                for (int i = 0; i < count; i++) {
                    View child = getChildAt(i);
                    LayoutParams params = (LayoutParams) child.getLayoutParams();
                    params.width = (int) (params.width * scaleX);
                    params.height = (int) (params.height * scaleY);
                    params.leftMargin = (int)(params.leftMargin * scaleX);
                    params.rightMargin = (int)(params.rightMargin * scaleX);
                    params.topMargin = (int)(params.topMargin * scaleY);
                    params.bottomMargin = (int)(params.bottomMargin * scaleY);
                }
                flag = true;
            }
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    

    相关文章

      网友评论

          本文标题:自定义像素适配

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