微信公众号开发 matlotlib golang firebase vuejs2 虚拟机 smtp seo progressjs alertifyjs jquery第一个子元素 js获取月份 windows查看进程命令 python基础 mysql删除表 python怎么调用函数 python支持中文 python免费教程 java入门 数据结构java版 java的泛型 java网课 java流程 java注释规范 java的安装 allowoverride 修改tomcat端口 js延迟加载的方式 3389扫描器 ansys安装教程 js代码混淆工具 国都证券官网下载 蜘蛛皮肤 backtrack4 淘宝店铺采集 操作系统安装 txplatform dnf选择角色卡死 刻刀工具 chrome访问助手
当前位置: 首页 > 学习教程  > 编程语言

Android屏幕适配之--自定义像素的缩放比例来实现屏幕适配

2020/8/31 15:37:31 文章标签:

在Android的适配中,可以采用自定义布局的形式,来通过计算像素的缩放比例来实现适配。大致思路就是,通过拿到设备实际的长宽像素值来除以参考设备的长宽值,得到这一个比例值,在设置控件的长宽值得时候,拿到开发者指定的长宽值乘以这个比例值,就能得到控件的实际显示大小了,公式大致如下:

scaleX = 设备实际像素值 / 参考设计图的像素值

控件实际像素值 = 开发者设置的像素值 * scaleX

实现方案如下:

首先我们通过一个工具类来获取设备在X方向和Y方向上的像素值比例

 

public class PixelUtils {

    private Context mContext;
    private static PixelUtils mUtils;

    //屏幕宽高
    private float mWidth;
    private float mHeight;

    //参考设备的屏幕尺寸,单位都是像素值px
    private float STANDARD_WIDTH = 720;
    private float STANDARD_HEIGHT = 1080;
    public PixelUtils(Context context) {
        mContext = context;
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if(manager != null){
            DisplayMetrics metrics = new DisplayMetrics();
            manager.getDefaultDisplay().getMetrics(metrics);    //获取屏幕的显示Metrics对象
            if(metrics.widthPixels > metrics.heightPixels){
                //横屏,宽高进行交换
                mWidth = metrics.heightPixels;
                mHeight = metrics.widthPixels;
            }else{
                //竖屏
                mWidth = metrics.widthPixels;
                mHeight = metrics.heightPixels;
            }
        }
    }

    public static PixelUtils getInstance(Context context){
        if(mUtils == null){
            mUtils = new PixelUtils(context.getApplicationContext());
        }
        return mUtils;
    }

    private int getStatusBarHeight(){
        int resId = mContext.getResources().getIdentifier("status_bar_height","dimen","android");
        if(resId > 0){
            return mContext.getResources().getDimensionPixelSize(resId);
        }
        return 0;
    }

    /**
     * 获取水平方向上的缩放比例
     */
    public float getXScal(){
        return mWidth / STANDARD_WIDTH;
    }

    /**
     * 获取竖直方向上的缩放比例
     */
    public float getYScal(){
        return mHeight / STANDARD_HEIGHT;
    }
}

接下来我们通过实现自定义控件(可以继承RelativeLayout或者LinearLayout等之类的),在onMeasure中,先拿到开发者设置的像素值,然后通过公式来乘以相应的比例,在把算出来的实际像素值设置给控件进行显示

 

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    if (!flag) {
        float scalX = PixelUtils.getInstance(getContext()).getXScal();
        float scalY = PixelUtils.getInstance(getContext()).getYScal();
        int childCount = getChildCount();

        for (int index = 0; index < childCount; index++) {
            View child = getChildAt(index);

            LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
            layoutParams.width = (int) (layoutParams.width * scalX);
            layoutParams.height = (int) (layoutParams.height * scalY);

            layoutParams.leftMargin = (int) (layoutParams.leftMargin * scalX);
            layoutParams.rightMargin = (int) (layoutParams.rightMargin * scalX);
            layoutParams.topMargin = (int) (layoutParams.topMargin * scalY);
            layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scalY);

        }
        flag = true;
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

在上面的代码中,我们定义了一个flag值来进行标记,主要是控件在进行二次绘制的时候,会在第一次绘制时设置的值得基础上在进行一次比例的计算,相当于实际值 = 设置的值 * 比例值 * 比例值,所以为了计算结果的准确,这里用一个flag值进行了标记

最后在自己的布局中就可以使用自己的自定义控件了,但是这里要注意的一点是,这里给控件设置的值应该是以目标尺寸为依据的像素值,所以单位应该是px

 

<com.example.fizzer.splashview.screen.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:orientation="horizontal"
tools:context=".screen.PixelActivity">
    

    <com.example.fizzer.splashview.screen.ScreenAdapterLayout
        android:layout_width="360px"
        android:layout_height="540px"
        android:orientation="horizontal"
        android:background="#ff0000">

        <TextView
            android:layout_width="180px"
            android:layout_height="270px"
            android:text="Fizzer"
            android:background="#0f0"/>
    </com.example.fizzer.splashview.screen.ScreenAdapterLayout>
</com.example.fizzer.splashview.screen.ScreenAdapterLayout>

这样的话就实现了整个的适配小效果,但是这种方案在实际操作上来说,局限性比较的大,在小范围的使用没问题,但是如果想要在整个项目中进行操作的话,建议还是采用通过修改系统的Density和DensityDpi的方案来进行适配。

 


本文链接: http://www.dtmao.cc/news_show_150370.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?