自定义View像素适配
当我们在手机屏幕上显示一个View 是,往往最为纠结的是它是否在不同的屏幕上显示的尺寸都一样了,不如UI小姐姐给我的参考尺寸是 720*1208 需要显示屏幕宽度的一半 360px
那么现在在1080*1920 的屏幕上 如果还是显示360px的画,就只会显示屏幕宽度的三分之一,但是根据需求,我们需要显示一半540px才对
那么我们怎么才能根据参考尺寸来计算我们不同手机屏幕的真实显示尺寸了?
我们用 屏幕的实际尺寸 除以 参考尺寸 再乘以 参考尺寸的宽度 即 1080/720*360=540px ,就可以得到我们想要显示的宽度了
其实就是根据像素的一个缩放比例 来计算实际的px值,下面我们就具体写代码来实现吧
新建一个工具类
public class Utils {
private static Utils utils;
//这里是设计稿参考宽高
private static final float STANDARD_WIDTH = 720;
private static final float STANDARD_HEIGHT = 1280;
//这里是屏幕显示宽高
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;
}
}
自定义一个View
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);
}
}
<?xml version="1.0" encoding="utf-8"?>
<com.rx.myapplication.ScreenAdapterLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:layout_width="360px"
android:layout_height="640px"
android:layout_marginLeft="10px"
android:text="Hello World!"
android:background="@color/colorAccent"
/>
</com.rx.myapplication.ScreenAdapterLayout>
可以看到当z在 7201280的手机上 当宽设置为 360px 高为640px 即 7201280 宽高的一半 其实现在scaleX scaleY 的缩放比例为一,可以看到效果,宽高各占一半
当在2160*1080 的手机上时,我们再看看效果,可以看到显示比例也是一样的