Android屏幕适配方法
2019-06-15 本文已影响30人
小米Metre
一、限定符适配
App会根据当前手机的分辨率自动选择对应的dimens.xml
1、优势
a、使用简单,不需要开发者手动指定
b、Google推荐的使用方式,由系统自己判断
c、适配通过不同的xml布局完成,不需要再写额外的代码实现。
2、劣势
a、增加Apk的大小,适配的机型越多,需要的xml就越多
b、适配所有机型的分辨率,xml文件会增加近3M左右
c、不能适配奇葩机型,比如手表等。
二、百分比适配
通过google 扩展的百分比控件实现(android-percent-support-extend)
1、优势
a、通过百分比定义高宽度,比较方便
b、彻底抛弃px dp 单位,通过百分比实现,可以在布局完成适配
c、对开发者工作量少
2、劣势
a、自定义控件无法适配
b、对代码侵入严重
三、代码动态适配
1、优势
a、跟设计效果图一致
b、大部分项目的实现方式
2、劣势
a、只能在java代码中实现
b、对代码侵入严重
3、实现代码
package com.example.uidynamicadapter.ui;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.WindowManager;
import android.widget.TextView;
import java.lang.reflect.Field;
/**
* 动态适配工具类
*/
public class UIUtil {
private static UIUtil instance;
//标准高宽度(根据设计图)
public static final float STANDARD_WIDTH = 1080f;
public static final float STANDARD_HEIGHT = 1920;
//实际设备信息
public static float displayMetricsWidth;
public static float displayMetricsHeight;
private static float systemBarHeight;
private UIUtil(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
systemBarHeight = getSystemBarHeight(context);
//判断横竖屏,再减去状态栏高度
if(displayMetrics.widthPixels > displayMetrics.heightPixels){
//横屏
displayMetricsWidth = displayMetrics.heightPixels;
displayMetricsHeight = displayMetrics.widthPixels - systemBarHeight;
}else{
//竖屏
displayMetricsWidth = displayMetrics.widthPixels;
displayMetricsHeight = displayMetrics.heightPixels - systemBarHeight;
}
}
/**
* 屏幕横竖切换是需要重新计算,调用该方法
* 可以在Activity onConfigurationChanged()中调用.
* @param context ctx
* @return UiUtil
*/
public static UIUtil notifyInstance(Context context){
instance = new UIUtil(context);
return instance;
}
public int getWidth(int width){
return Math.round(width * displayMetricsWidth / STANDARD_WIDTH);
}
public int getHeight(int height){
return Math.round(height * displayMetricsHeight / (STANDARD_HEIGHT - 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",18);
}
private int getValue(Context context,String dimenClass,String system_bar_height,int defaultValue){
//dimenClass:com.android.internal.R$dimen
//system_bar_height:system_bar_height
try {
Class<?> clazz = Class.forName(dimenClass);
Object object = clazz.newInstance();
Field field = clazz.getField(system_bar_height);
int id = Integer.parseInt(field.get(object).toString());
return context.getResources().getDimensionPixelSize(id);
}catch (Exception e){
e.printStackTrace();
}
return defaultValue;
}
public static UIUtil getInstance(Context context){
if(instance == null){
instance = new UIUtil(context);
}
return instance;
}
public static UIUtil getInstance(){
if(instance == null){
throw new RuntimeException("instance was null");
}
return instance;
}
//字体适配
public static void setTextSize(TextView tv,int size){
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,getInstance().getHeight(size));
}
}