关于android 屏幕适配的一些笔记

我们知道dp是与屏幕无关的,那么我们开发中便可以根据屏幕宽度大小设置对应的dp值

关于android 屏幕适配的一些笔记

 

如图,默认的values文件夹是指宽度为360dp的屏幕,如何计算我们的手机屏幕的宽度呢,首先我们要获得屏幕的密度density,

DisplayMetrics dm = new DisplayMetrics();
dm = getActivity().getApplicationContext().getResources().getDisplayMetrics();
float density = dm.density;

比如小米6的density为3.0,红米8A为2,,小米note3为2.75

然后 dp=px/density;

小米6 宽1080px,dp=1080/3.0=360

红米8A 宽720px,dp=720/2.0=360

小米note3 宽1080,dp=1080/2.75=392

换言之 当我们使用value时小米6与小米8A会去values文件里面找,小米note3会去values-w392dp文件里面找。

最后我们要设置不同dp文件里面的values值

values 

<dimen name="dp_1">1dp</dimen>

values-w384dp

<dimen name="dp_1">1.07dp</dimen>

values-w392dp

<dimen name="dp_1">1.09dp</dimen>

其实就是倍数关系 values-w392dp 下面dp_1 的值就是values 下面dp_1 的值*(392/360)(360dp下面dp_1的值我设置为1dp)

自己将各文件夹值各一套写好,在页面开发的时候就可以使用了。

然后注意一点,比方说我们有一个场景是需要动态添加一个跟布局一样大小的textview,拿上面的8A与not3做测试

首先我们布局 如果宽高采用360dp,那么我们在所有手机上面创建的都是宽高为360dp的textview

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/order_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tv1"
        android:layout_width="360dp"
        android:layout_height="360dp"
        android:textColor="#FFFFFF"
        android:background="#000000"
        />

</LinearLayout>

动态添加

TextView tv=new TextView(mContext);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams((int)ToolsUtil.dp2px_New(mContext,360),(int)ToolsUtil.dp2px_New(mContext,360));
tv.setLayoutParams(params);
tv.setBackgroundColor(getResources().getColor(R.color.app_bottom_text_color));
order_layout.addView(tv);
public static float dp2px_New(Context context, float dp) {

    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
}

记住宽高传的是360,但是这种做法是没有适配,出现的现象就是8A宽度沾满屏幕,note3还差一些,因为8A屏幕宽度是360dp,note3是392dp.

现在用我们上面做的适配来看看结果,代码更改

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/order_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tv1"
        android:layout_width="@dimen/dp_360"
        android:layout_height="@dimen/dp_360"
        android:textColor="#FFFFFF"
        android:background="#000000"
        />

</LinearLayout>

动态添加

TextView tv=new TextView(mContext);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams((int) getResources().getDimension(R.dimen.dp_360),(int) getResources().getDimension(R.dimen.dp_360));
tv.setLayoutParams(params);
tv.setBackgroundColor(getResources().getColor(R.color.app_bottom_text_color));
order_layout.addView(tv);

再测测试你会发现,textview是占满屏幕的,不论是not3还是8A,android 系统会根据屏幕去不同的valuse下面找对应的值,小米note3就是392dp,8A就是360dp

最后在做一个小笔记

getDimension
获取某个dimen的值,如果是dp或sp的单位,将其乘以density,如果是px,则不乘 返回float

getDimensionPixelOffset
获取某个dimen的值,如果是dp或sp的单位,将其乘以density,如果是px,则不乘 返回int

getDimensionPixelSize
则不管写的是dp还是sp还是px,都会乘以denstiy.
在android里面系统的标准单位是px,像上述系统从不同的values获得dp后会再乘以屏幕密度获取px值。

需要验证的可以用下面这段代码

tv1.post(new Runnable() {
    @Override
    public void run() {
        Log.d("bnbn","获取对应的px值"+getResources().getDimension(R.dimen.dp_360)+"");//获取某个dimen的值,如果是dp或sp的单位,将其乘以density,如果是px,则不乘 返回float
        DisplayMetrics dm = new DisplayMetrics();
        dm = getActivity().getApplicationContext().getResources().getDisplayMetrics();
        float density = dm.density;
        Log.d("bnbn","density="+dm.density+"");
        Log.d("bnbn","获取对应的dp值"+getResources().getDimension(R.dimen.dp_360)/density+"");

    }
});