美文网首页
屏幕适配

屏幕适配

作者: 往事一块六毛八 | 来源:发表于2020-04-17 16:52 被阅读0次

常见概念

屏幕尺寸

屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米

屏幕分辨率

屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素横向像素,如19601080。

屏幕像素密度

屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。

dp、dip、dpi、sp、px
  • px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等。
  • dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px以此类推。

假如同样都是画一条320px的线,在480800分辨率手机上显示为2/3屏幕宽度,在320480的手机上则占满了全屏,如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。这也是为什么在Android开发中,写布局的时候要尽量使用dp而不是px的原因。

  • sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。

android中的dp在渲染前会将dp转为px,计算公式:

  • px = density * dp;
  • density = dpi / 160;
  • px = dp * (dpi / 160);
    获取手机设备密度:
    float density=context.getResource().getDisplayMetrics().density;

屏幕尺寸、分辨率、像素密度三者关系

image.png image.png

目前市面上的屏幕适配方案

  • 今日头条的修改设备密度方案
  • 最小宽度限定符
    现在有screenMatch插件 选中app目录然后点击screenMath


    image.png
    image.png

在values目录中新建dimens文件将


image

将改文件中的内容全部考到dimens文件中

image.png

将要适配的目录填写 ,剩下的就是要忽略的

然后在执行选中screenMatch文件


最后生成下面文件


image.png

布局中根据尺寸直接写:


image.png
  • 自定义适配布局
public class ScreenAdaptationRelaLayout extends LinearLayout {
    public ScreenAdaptationRelaLayout(Context context) {
        super(context);
    }

    public ScreenAdaptationRelaLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScreenAdaptationRelaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    static boolean isFlag = true;

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {


        if(isFlag){
            int count = this.getChildCount();
            float scaleX =  UIUtils.getInstance(this.getContext()).getHorizontalScaleValue();
            float scaleY =  UIUtils.getInstance(this.getContext()).getVerticalScaleValue();

            Log.i("testbarry","x系数:"+scaleX);
            Log.i("testbarry","y系数:"+scaleY);
            for (int i = 0;i < count;i++){
                View child = this.getChildAt(i);

                //代表的是当前空间的所有属性列表
                LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
                layoutParams.width = (int) (layoutParams.width * scaleX);
                layoutParams.height = (int) (layoutParams.height * scaleY);
                layoutParams.rightMargin = (int) (layoutParams.rightMargin * scaleX);
                layoutParams.leftMargin = (int) (layoutParams.leftMargin * scaleX);
                layoutParams.topMargin = (int) (layoutParams.topMargin * scaleY);
                layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scaleY);
            }
            isFlag = false;
        }



        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

public class UIUtils {

   private Context context;

   private static UIUtils utils ;

   public static UIUtils getInstance(Context context){
       if(utils == null){
           utils = new UIUtils(context);
       }
       return utils;
   }


   //参照宽高
   public final float STANDARD_WIDTH = 720;
   public final float STANDARD_HEIGHT = 1232;

   //当前设备实际宽高
   public float displayMetricsWidth ;
   public float displayMetricsHeight ;

   private  final String DIMEN_CLASS = "com.android.internal.R$dimen";


   private UIUtils(Context context){
       this.context = context;
       //
       WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

       //加载当前界面信息
       DisplayMetrics displayMetrics = new DisplayMetrics();
       windowManager.getDefaultDisplay().getMetrics(displayMetrics);

       if(displayMetricsWidth == 0.0f || displayMetricsHeight == 0.0f){
           //获取状态框信息
           int systemBarHeight = getValue(context,"system_bar_height",48);

           if(displayMetrics.widthPixels > displayMetrics.heightPixels){
               this.displayMetricsWidth = displayMetrics.heightPixels;
               this.displayMetricsHeight = displayMetrics.widthPixels - systemBarHeight;
           }else{
               this.displayMetricsWidth = displayMetrics.widthPixels;
               this.displayMetricsHeight = displayMetrics.heightPixels - systemBarHeight;
           }

       }
   }

   //对外提供系数
   public float getHorizontalScaleValue(){
       return displayMetricsWidth / STANDARD_WIDTH;
   }

   public float getVerticalScaleValue(){

       Log.i("testbarry","displayMetricsHeight:"+displayMetricsHeight);
       return displayMetricsHeight / STANDARD_HEIGHT;
   }



   public int getValue(Context context,String systemid,int defValue) {

       try {
           Class<?> clazz = Class.forName(DIMEN_CLASS);
           Object r = clazz.newInstance();
           Field field = clazz.getField(systemid);
           int x = (int) field.get(r);
           return context.getResources().getDimensionPixelOffset(x);

       } catch (Exception e) {
          return defValue;
       }
   }
}

布局中引入:

<com.dongnao.lsn_9_screenadapter.ScreenAdaptationRelaLayout
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
     <Button
         android:layout_width="@dimen/dp_150"
         android:layout_height="wrap_content"
         android:text="test1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.0" />

     <Button
         android:layout_width="@dimen/dp_200"
         android:layout_height="wrap_content"
         android:text="test1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.1" />
     <Button
         android:layout_width="@dimen/dp_150"
         android:layout_height="wrap_content"
         android:text="test1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.2" />
     <Button
         android:layout_width="@dimen/dp_150"
         android:layout_height="wrap_content"
         android:text="test1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.3" />
     <Button
         android:layout_width="@dimen/dp_150"
         android:layout_height="wrap_content"
         android:text="test1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.4" />


 </com.dongnao.lsn_9_screenadapter.ScreenAdaptationRelaLayout>

  • 第三方库的适配方案

https://www.jianshu.com/p/7da141e682c7
https://juejin.im/post/5bce688e6fb9a05cf715d1c2
https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

相关文章

  • 屏幕适配总结

    屏幕适配总结 为什么要针对屏幕做适配 drawable目录常见问题 : 屏幕适配方案:

  • Android屏幕适配-应用篇

    目录 Android屏幕适配-基础篇Android屏幕适配-应用篇 Android屏幕适配最主要的原因:  是由于...

  • 屏幕适配的那些坑

    屏幕适配的那些坑 屏幕适配的那些坑

  • LayaAir屏幕适配

    LayaAir屏幕适配 官方教程链接:LayaAir实战开发11-屏幕适配 屏幕适配 随着移动端设备(手机、平板、...

  • she

    1.适配的分类 系统适配 屏幕适配 1.1屏幕适配历史 1.1.1autoresizing 去掉auto layo...

  • Android屏幕适配

    一. 为什么要适配屏幕 android屏幕大小、屏幕密度碎片化严重 二. 怎么样适配屏幕 图片适配 应用图标提供不...

  • 屏幕适配AutoResizing

    适配器简介 AutoResizing 屏幕适配的历史 -iPhonestyGS\IPhone4 -没有屏幕适配可言...

  • css media 适配屏幕宽度

    H5 屏幕适配 css media 适配屏幕宽度;js 通过 适配获取屏幕宽度,来执行对应方法; max-widt...

  • 关于iOS适配的一点事

    屏幕适配及文字适配

  • Android屏幕适配(4)常见:第三种

    前言:Android屏幕适配(1)基础知识篇Android屏幕适配(2)常见:第一种Android屏幕适配(3)常...

网友评论

      本文标题:屏幕适配

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