美文网首页Android开发适配Android开发
屏幕适配:修改屏幕像素密度,随便设dp

屏幕适配:修改屏幕像素密度,随便设dp

作者: space0o0 | 来源:发表于2019-10-21 10:42 被阅读0次

前提

平时xml中view的宽高单位都是dp居多,我们的设计师一般会选择一款机型的屏幕尺寸作为设计的目标尺寸。

那么,如何根据目标尺寸的屏幕密度,适配我们种类繁多的机型?

实现目标

将以dp作为单位,以目标尺寸标注的宽高,和当前机型的比例,动态进行屏幕适配。
例如:设计尺寸为360dp宽,我们的view设置180dp宽。那么,该view在任何屏幕尺寸下,都将占用屏幕一半的尺寸;

了解参数

在上代码前,先了解下待会用到的参数含义:

  • density
    当前机型的屏幕密度,标准屏幕密度是每平方英寸有160个像素,如果当前机型每平方英寸有320个像素,即density = (320 / 160)= 2;
  • scaleDensity
    代表的是字体的屏幕密度,默认情况下:scaleDensity = density;
  • densityDpi
    表示的就是每平方英寸显示的像素点个数。
    如:160个像素点 即densityDpi=160;

上代码

代码其实非常简单,直接从DisplayMetrics中获取。

    private final static float WIDTH = 360;//适配机型的宽为360dp,屏幕宽/屏幕密度=360dp

    private static float appDensity;
    private static float appScaleDensity;

    public static void setDensity(Application application, Activity activity) {
        //获取当前app的屏幕显示信息
        DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();

        appDensity = displayMetrics.density;
        appScaleDensity = displayMetrics.scaledDensity;

        //计算等比缩放后的density和scaleDensity
        //WIDTH相对于所有屏幕宽度都是相等的,它是用dp作为单位,所以 屏幕宽度/屏幕密度=WIDTH
        //targetDensity = targetWidht/WIDTH
        float targetDensity = displayMetrics.widthPixels / WIDTH;
        //appScaleDensity/appDensity=targetScaleDensity/targetDensity;
        float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
        int targetDensityDpi = (int) (targetDensity * 160);

        //替换activity的density,appdensity,densityDpi
        DisplayMetrics aDisplayMertics = activity.getResources().getDisplayMetrics();
        aDisplayMertics.density = targetDensity;
        aDisplayMertics.scaledDensity = targetScaleDensity;
        aDisplayMertics.densityDpi = targetDensityDpi;
    }
}

思路讲解,计算

首先我们需要获取当前机型的屏幕密度信息:appDensity,appScaleDensity

我们的设计尺寸会根据默认机型计算出一个固定的以dp为单位的宽度:WIDTH

比如:默认机型的宽高为1080*1920,该设备的屏幕密度为3
那么WIDTH = 1080/3 = 360dp;因此所有适配机型的宽也就等于360dp。
根据 屏幕宽度 / 屏幕密度=WIDTH公式,现在知道屏幕宽度和WIDTH,也就能求出:屏幕密度=屏幕宽度 / WIDHT;

现在屏幕宽度(dp):targetDensity = displayMetrics.widthPixels / WIDTH 求出。

接下来,就需要求出适配机型的scaleDensity

appScaleDensity / appDensity = targetScaleDensity / targetDensity ;

targetScaleDensity = targetDensity * (appScaleDensity / appDensity) ;

densityDpi = density * 160 ;

最后,把获取到的数据,设置到activity的displayMetrics中。

计算出来后,我们需要在绘制view之前先设置好

在onCreate中的setContentView之前添加

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
      //在绘制前设置density
    DensityUtils.setDensity(this.application, this)
    setContentView(R.layout.activity_screen_adapter2)
}

现在,我们的设计尺寸宽度为360dp,我们设置view的宽度为180dp,应该是占用屏幕一半尺寸。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android”
    xmlns:tools=“http://schemas.android.com/tools”
    android:layout_width=“match_parent”
    android:layout_height=“match_parent”
    tools:context=“.screenAdapter2.ScreenAdapter2Activity”>

    <TextView
        android:id=“@+id/tv1”
        android:layout_width=“180dp”
        android:layout_height=“180dp”
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:background="#f00" />

    <TextView
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_below="@id/tv1"
        android:layout_toRightOf="@id/tv1"
        android:background="#0f0" />

</RelativeLayout>

显示效果:


device-2019-10-21-102743.png

字体的缩放监听

以上代码在字体发生改变时,不会根据字体设置相应的发生改变
我们需要监听字体改变事件,再重新计算scaleDensity;

//完整代码
public static void setDensity(final Application application, Activity activity) {
    //获取当前app的屏幕显示信息
    DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();

    appDensity = displayMetrics.density;
    appScaleDensity = displayMetrics.scaledDensity;

    //监听字体改变,重新获取scaleDensity
    application.registerComponentCallbacks(new ComponentCallbacks() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            if (newConfig != null && newConfig.fontScale > 0) {
                appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
            }
        }

        @Override
        public void onLowMemory() {

        }
    });

    //计算等比缩放后的density和scaleDensity
    //WIDTH相对于所有屏幕宽度都是相等的,它是用dp作为单位,所以 屏幕宽度/屏幕密度=WIDTH
    //targetDensity = targetWidht/WIDTH
    float targetDensity = displayMetrics.widthPixels / WIDTH;
    //appScaleDensity/appDensity=targetScaleDensity/targetDensity;
    float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
    int targetDensityDpi = (int) (targetDensity * 160);

    //替换activity的density,appdensity,densityDpi
    DisplayMetrics aDisplayMertics = activity.getResources().getDisplayMetrics();
    aDisplayMertics.density = targetDensity;
    aDisplayMertics.scaledDensity = targetScaleDensity;
    aDisplayMertics.densityDpi = targetDensityDpi;
}
![QQ20191012-122912.png](https://img.haomeiwen.com/i1982159/bccbae9c9d2e1fd8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

相关文章

  • 屏幕适配:修改屏幕像素密度,随便设dp

    前提 平时xml中view的宽高单位都是dp居多,我们的设计师一般会选择一款机型的屏幕尺寸作为设计的目标尺寸。 那...

  • Android适配方案

    1、设备宽度的dp计算方法 dp = 屏幕像素宽度/(屏幕像素密度/160) 160是基准屏幕像素密度 ...

  • 屏幕适配-像素密度

    屏幕适配-像素密度 原理:修改density,scaleDensity,densityDpi值,直接更改系统内部对...

  • Android 屏幕适配-像素密度适配

    承接Android 屏幕适配 说明:本文仅为简单思路,没有实现项目适用的轮子 通过修改系统像素密度做屏幕适配的主要...

  • 适配

    屏幕适配: 像素: px 像素密度: dpi(px/inch)...

  • Android屏幕适配获取尺寸信息沉侵式标题栏

    屏幕适配 dip和dp是一个意思,Density Independent Pixels的缩写,即密度无关像素,而s...

  • Drawable Bitmap

    当屏幕密度为160时,1dp = 1px(像素)当屏幕密度为320时,1dp = 2px(像素) 以此类推 D...

  • Android屏幕适配

    为什么需要屏幕适配? 手机型号屏幕分辨率屏幕密度实际屏幕宽(dp)华为Mate91080*1920440393荣耀...

  • Android屏幕适配

    Android屏幕适配 概述 屏幕适配的主要目标有两个,不同屏幕尺寸的适配和不同像素密度的适配。随着手机行业发展异...

  • Android屏幕适配

    Android屏幕适配主要包含三个方面 屏幕像素密度(ldpi,mdpi,hdpi,xhdpi,xxhdpi,xx...

网友评论

    本文标题:屏幕适配:修改屏幕像素密度,随便设dp

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