我们知道dp是与屏幕无关的,那么我们开发中便可以根据屏幕宽度大小设置对应的dp值
如图,默认的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+""); } });