一、为什么要适配
因为Android市场的碎片化,导致APP界面再不同屏幕上显示的尺寸不一致。适配可以让布局,资源,用户流程匹配不同的屏幕。
二、布局的适配
1.不要写尺寸
2.LinearLayout的权重
3.RelativeLayout的布局方式
4.ContraintLayout
5.Percent-Layout来进行布局
三、图片资源适配
1.使用.9的图片
2.使用SVG实现缩放
3.使用多种尺寸的mipmap资源
四、用户流程适配
1.手机和平板不同的流程
五、限定符的适配
1.分辨率限定符 drawable-hdpi drawable-xdpi
2.尺寸限定符layout-small,layout-large
3.最小宽度的限定符values-sw ...
屏幕方向的限定符layout-land,layout-port
六、刘海屏的适配
根据各个厂商的官方文档适配
七、自定义View的适配
根据设计稿获取到缩放比例,在 View Measure的时候更改View的尺寸
缩放比例 = 使用设备尺寸 / 设计尺寸
获取缩放尺寸的工具类
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import java.lang.reflect.Field;
public class UIUtils {
// 工具类
private static UIUtils instance;
// 参考设备的宽和高 用来计算缩放比例
public static final float STANDARD_WIDTH = 1080f;
public static final float STANDARD_HEIGHT = 1920f;
//实际设备信息 赋值 他是不知道横竖 1080 1920
public static float displayMetricsWidth;
public static float displayMetricsHeight;
// 状态栏的宽高
public static float systemBarHeight;
// applicaiton
public static UIUtils getInstance(Context context) {
if (instance == null) {
instance = new UIUtils(context);
}
return instance;
}
public static UIUtils notityInstance(Context context) {
instance = new UIUtils(context);
return instance;
}
// activity
public static UIUtils getInstance() {
if (instance == null) {
throw new RuntimeException("UiUtil应该先调用含有构造方法进行初始化");
}
return instance;
}
private UIUtils(Context context) {
// 获取设备的宽高
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
// 获取到屏幕的宽高
if (displayMetricsWidth == 0.0f || displayMetricsHeight == 0.0f) {
//在这里得到设备的真实值
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
systemBarHeight = getSystemBarHeight(context);
//横屏
if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
this.displayMetricsWidth = (float) (displayMetrics.heightPixels);
this.displayMetricsHeight = (float) (displayMetrics.widthPixels - systemBarHeight);
} else {
// 竖屏
this.displayMetricsWidth = (float) (displayMetrics.widthPixels);
this.displayMetricsHeight = (float) (displayMetrics.heightPixels - systemBarHeight);
}
// 状态栏
}
}
//
public float getHorizontalScaleValue() {
return ((float) (displayMetricsWidth)) / STANDARD_WIDTH;
}
public float getVerticalScaleValue() {
return ((float) (displayMetricsHeight)) / (STANDARD_HEIGHT - systemBarHeight);
}
private int getSystemBarHeight(Context context) {
return getValue(context, "com.android.internal.R$dimen", "system_bar_height", 48);
}
public int getWidth(int width) {
return Math.round((float) width * this.displayMetricsWidth / STANDARD_WIDTH);
}
public int getHeight(int height) {
return Math.round((float) height * this.displayMetricsHeight / (STANDARD_HEIGHT - systemBarHeight));
}
private int getValue(Context context, String dimeClass, String system_bar_height, int defaultValue) {
// com.android.internal.R$dimen system_bar_height 状态栏的高度
try {
Class<?> clz = Class.forName(dimeClass);
Object object = clz.newInstance();
Field field = clz.getField(system_bar_height);
int id = Integer.parseInt(field.get(object).toString());
return context.getResources().getDimensionPixelSize(id);
} catch (Exception e) {
e.printStackTrace();
}
return defaultValue;
}
}
重写容器View,让容器View中的控件都被缩放
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (flag) {
flag = false;
// 获取水平和数值方向的缩放比例
float scaleX = UIUtils.getInstance(getContext()).getHorizontalScaleValue();
float scaleY = UIUtils.getInstance(getContext()).getVerticalScaleValue();
int childCount = this.getChildCount();
// 缩放所有子控件
for (int i = 0; i < childCount; i++) {
View child = this.getChildAt(i);
LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
layoutParams.width = (int) (layoutParams.width * scaleX);
layoutParams.height = (int) (layoutParams.height * scaleY);
layoutParams.leftMargin = (int) (layoutParams.leftMargin * scaleX);
layoutParams.rightMargin = (int) (layoutParams.rightMargin * scaleX);
layoutParams.topMargin = (int) (layoutParams.topMargin * scaleY);
layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scaleY);
}
}
}
网友评论