适配

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));
    }
}

上一篇下一篇

猜你喜欢

热点阅读