关于android UI适配的一些思考

2023-05-16

作为前端工程师,界面效果,效率。肯定是第一要务。面对安卓庞大的机型和屏幕对开发者的要求也就越来越高了。今天笔者就自己对UI适配的一些经验进行一个简短的总结。

1.关于xml中写死dp的思考
首先我们应该先把问题抛出,如果我们在xml把控件的宽度和高度写死,比如

 <TextView
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="asdasdasd"
            />

相信大多时候都可以这么写,因为Android dp这个单位就是为了适配屏幕而出现的控件长度单位,它会让100dp在不同的手机不同的屏幕尺寸都有相似的表现。
为什么是相似的表现而不是绝对的表现呢?因为不同的设备,横向和纵向所拥有的dp很可能是不同的,一般手机横向dp在360dp左右,也就是说,如果你写了一个宽度为180dp的控件,在一些手机可能有屏幕的一般宽,有一些手机超过一般,有一些手机不到一半。

我们写这样的一段代码,然后看一下xml的预览效果:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#123333"
    android:id="@+id/container"
    android:layout_width="360dp"
    android:layout_height="match_parent">

</LinearLayout>

这里写图片描述

这里写图片描述

这里写图片描述
2.关于java动态写控件大小的思考

我们看到360dp在不同设备的所表现的占屏比是不同的。如果我们写数值比较小的dp相信直接写死的问题不大。但是如果设计稿上某个控件的宽度你换算完刚好是340dp怎么,肯定不能写340dp。其实我们可以用match_parent然后用padding margin之类的东西,在左右留一个小数值dp的距离,来实现效果。但是如果这个控件要求是高度和宽度的比例是固定的,比如展示一个广告浮层的图片,那么xml估计就无法锁定宽高比了,我们就必须借助java代码来决定这个控件高度:

RelativeLayout.LayoutParams mLayoutParams = 
new RelativeLayout.LayoutParams (mHeight,mWidth);
mLayoutParams.addRule(RelativeLayout.ALIGN_TOP, R.id.supernatant);
mLayoutParams.addRule(RelativeLayout.ALIGN_LEFT, R.id.supernatant);
bigSupernatantImgLayoutParams.setMargins(DPIUtil.dip2px(9f), 0, 0, 0);
bigImg.setLayoutParams(mLayoutParams);

类似这样宽度和高度都是活的,我们可以通过获取屏幕的实际宽高像素,来通过等比,相似等一些算法,转换出比例和UI设计图一样的UI,但是最大的弊端应该就是,这么书写会让java代码比较多,比较乱。因此会有一些百分百布局框架等,其实思路都类似,等比缩放就是很核心思路。
有个轻量的方法也就是写个工具类算出设计图到手机屏幕的转换关系:

public static int getHeightByValue720(int mValue) {
return (int) ((float) (DPITools.getHeight() * nDesignValue) / (float) 1280);
    }

public static int getWidthByValue720(int mValue) {
return (int) ((float) (DPITools.getWidth() * nDesignValue) / (float) 720);
    }

这个方法就是如果是720的设计稿,我们将设计稿的值转换为在所用设备下同比例的大小。这似乎很完美。
如果设计给的控件大小是 100X200 ,那么如果运行在1080p的设配上。我们动态得到控件的大小是150X300.很开心,1080的横向纵向像素是720的1.5倍,控件也大了1.5倍这,的确没毛病。但是我们可能低估了安卓阵营了。

3。关于动态宽高写布局的一些思考。

三星Galaxy S8分辨率:
2960*1440 (570 ppi)

如果按照上述方式我们在三星Galaxy S8上运行效果会是如何呢?结果是200X462。控件已经倍拉伸了,原因就是S8的屏幕比例不是16比9所以,按照原来的方式缩放,就会造成拉伸,为此市面上也有解决方案:

public static int getValueByValue720(int mValue) {
return (int) ((float) (DPITools.getWidth() * nDesignValue) / (float) 720);
    }

就是无论宽度还是高度,都是用宽度缩放,那么刚才控件在S8上得到的数值就是200X400.控件不会被拉伸,由于现在大多界面都是可以Scroll的,那么就算高度不标准问题也不大,我们比如一个listview我们保证在16比9的手机上,能正好展示4个item,在16比10的手机上展示3个半item,在18.5比9的设备上展示4个半item,这个设计产品还是用户都是可以接受的。

4。关于动态宽度为基准写布局的一些思考。
然而关于方法三又存在一些问题,设想下面一个场景,页面里展示的是一个cardview,cardview的背景是一张图片,所以cardview宽高必须固定,这个cardview又是不允许上下滑动的,里面又有很多控件,在16比9的设计稿上,cardview里面的控件,排列整齐,最后也没什么太大的边界。

类似:

这里写图片描述

这样面临一个问题,如果在16比10的手机上,其实每次计算出的高度都是大于手机比例的,因此cardview后面的几个控件可能无法正常显示,或被拉伸。在18.5比9的手机上,cardview下面可能有空余,或者根据不同layout方式,可能其他地方有空余。我认为这还是可以接受的,比较这种手机是少数,但是控件被挤压就难以接受了。归纳起来也就说,如果这种不能上下滑动的view,可以让它有空余,但是不能让它挤压。我们可以使用一个保守的方法,判断手机是否是大于16比9,如果大于就说明手机比较瘦高,如果小于就说明手机比较胖。我们就可以用相对充裕的方法计算控件宽高,来保证控件不被挤压。

public static boolean bigThan169() {
        float h = DPIUtil.getHeight();
        float w = DPIUtil.getWidth();
        if ((h / w) > 1.78f) return true;
        else return false;
    }
if (bigThan169())
newWidth = DPIUtil.getWidthByDesignValue720(DesignWidth);(以宽度为基准)
else newWidth = DPIUtil.getHeightByDesignValue720(DesignWidth);(以高度为基准 从而保证控件上下高度够用)

总之就这就是一个保守,保证控件装得下的思路,若果是控件横向被挤压也是一样的。我们为了保证显示的下,缩小了控件。

总结:UI适配愈走愈远,有时也要和设计师产品经理协调,不要设计一些容易触发适配问题的页面,减少安卓端的适配压力,但是如果场景真的无法避免,我们就只能有更优雅的方式去解决适配问题。

上述个人经验体会如有疑问欢迎讨论。

哪里可以找到我:

我的Github: https://github.com/AndroidMsky

我的博客主页: http://blog.csdn.net/androidmsky

欢迎加作者自营安卓开发交流群:

308372687

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于android UI适配的一些思考 的相关文章

随机推荐

  • 写给4年前开始编程序的自己

    最近在网上看到有人写了一篇关于 写给4年前没有开始做设计的自己 xff0c 突然也想写这样一篇文章 具体那篇文章的内容我并没有细读 xff0c 防止自己的思路照着他的来 首先 xff0c 我先简单介绍下自己 xff0c 好为后面的内容做一个
  • STM32单片机(七). USART串口、IIC和CAN通信

    在简单的学习过了STM32中的简单外设以及中断系统后 xff0c 在本章节中开始介绍STM32芯片中各个通信接口的配置 在计算机中 xff0c 按数据传输方式可分为串行通信以及并行通信 xff1b 按数据同步方式可分为异步通信和同步通信 x
  • VINS-Mono论文笔记(中)

    VINS Mono论文笔记 中 前言1 初始化过程1 1 视觉重构1 2 视觉惯性联合 2 紧耦合的单目VIO系统2 1 公式2 2 imu残差2 3 视觉残差2 4 边缘化残差2 5 针对相机实时帧率的纯运动视觉惯性状态估计器2 6 im
  • Qt生成exe文件并成功运行

    Qt程序写完后 xff0c 想要生成一个exe文件 xff0c 那么可以参考以下方法 工具 xff1a Qt5 9 9 我们以程序2048为例 将左下角debug改为release xff0c 然后点击左侧 项目 xff0c 找到build
  • 【Qt入门第二篇】基础(二)编写Qt多窗口程序

    导语 程序要实现的功能是 xff1a 程序开始出现一个对话框 xff0c 按下按钮后便能进入主窗口 xff0c 如果直接关闭这个对话框 xff0c 便不能进入主窗口 xff0c 整个程序也将退出 当进入主窗口后 xff0c 我们按下按钮 x
  • Qt之统一的UI界面格式基调,漂亮的UI界面

    今天主要谈谈Qt UI界面统一样式 格式基调 的问题 xff1b 例如在window系统上 xff0c 几乎所有的窗口都有标题栏和状态栏以及中央部件 xff0c 而且每一个标题栏和状态栏以及中央部件样式都保持一致的 xff1b 但是在实际开
  • qt plaintextedit使用_qt获取lineedit的内容

    QLineEdit和QTextEdit都是文本框类 xff0c QLineEdit类是单行文本框控件 xff0c 可以输入单行字符串 QTextEdit类是多行文本框控件 xff0c 可以显示多行文本内容 xff0c 当文本内容超出控件显示
  • Qt实现表格控件

    一 概述 最近在研究QTableView支持多级表头的事情 xff0c 百度了下网上资料还是挺多的 实现的方式总的来说有2种 xff0c 效果都还不错 xff0c 最主要是搞懂其中的原理 xff0c 做到以不变应万变 实现多级表头的方式有以
  • 从h5调起原生APP到自己调起知乎页面

    转载请注明作者AndroidMsky和出处 xff1a http blog csdn net AndroidMsky article details 54316327 效果 xff1a 这篇算兴趣加技术篇 xff0c 和之前的抢红包博文和接
  • Qt经验-按钮长按事件分析

    引言 最近在做qt项目 xff0c 需要对button按钮添加一个长按事件 xff08 比如点击按钮 xff0c 开始运动 松开按钮 xff0c 运动停止 xff09 查了些许资料 xff0c xff08 差点误把QPushButton的p
  • Qt开发-鼠标事件

    引言 个人认为 xff0c 事件机制是Qt最难以理解且最为精妙的一部分 事件主要分为两种 xff1a 在与用户交互时发生 比如按下鼠标 xff08 mousePressEvent xff09 xff0c 敲击键盘 xff08 keyPres
  • Qt Creator工具介绍与使用

    如今 Qt Creator 功能十分强大了 xff0c 包含项目模板生成 代码编辑 UI 设计 QML 界面编辑 调试程序 上下文帮助等丰富功能 xff0c 本文就详细的介绍一下如何使用 Qt 在很长的一段时间内都没有自己的开发环境 xff
  • Qt 封装HTTP网络工具类HttpClient

    一 前言 Qt 使用 QNetworkAccessManager 访问网络 xff0c 这里对其进行了简单的封装 xff0c 访问网络的代码可以简化为 1 GET 请求无参数 HttpClient 34 http localhost 808
  • Qt——线程与定时器

    一 定时器QTimer类 The QTimer class provides repetitive and single shot timers The QTimer class provides a high level programm
  • MQTT连接阿里云IoT

    我们先来看看官方提供的MQTT连接说明 xff0c 如下 xff1a 根据该文档 xff0c 我们大致了解了各个参数的封装方式 xff0c 那么接下来我们就通过QtMqtt的接口来传入这些参数并连接到阿里云IOT 代码片段 来看一些基本的参
  • Qt小程序之QQ登录窗口输入框控件

    代码之路 整体思路即根据focusInEvent和focusOutEvent事件判断焦点是否在输入框中 xff0c 同时重写setPlaceholderText方法 xff0c 把最开始设置的占位字符保存下来 xff0c 然后焦点进入的时候
  • Qt 自定义日志类

    一 前言 C 43 43 中比较不错的日志工具有 log4cxx xff0c log4qt 等 xff0c 但是它们都不能和 qDebug qInfo 等有机的结合在一起 xff0c 所以在 Qt 中使用总觉得不够舒服 xff0c 感谢 Q
  • 在Qt程序中使用C++11线程std::thread处理耗时操作

    Qt界面程序通常什么情况下要使用到线程 xff1f Qt界面程序在调用接口处理时间较长的任务时 如连接网络 复制文件等等耗时操作 xff0c 界面在等待接口返回前会导致卡死 为了不让界面卡死 xff0c 可以使用一个子线程来处理耗时任务 x
  • 学习stm32单片机,必备工具和软件,你知道几个?

    大家好 xff0c 我是华维的麦琪 今天给大家介绍下 xff0c 学习stm32需要用到那些硬件和软件 xff0c 对于学习stm32单片机的学习者 xff0c 要添置必要的学习和开发工具 xff0c 搭建一个最基本的学习平台 xff0c
  • 关于android UI适配的一些思考

    作为前端工程师 xff0c 界面效果 xff0c 效率 肯定是第一要务 面对安卓庞大的机型和屏幕对开发者的要求也就越来越高了 今天笔者就自己对UI适配的一些经验进行一个简短的总结 1 关于xml中写死dp的思考 首先我们应该先把问题抛出 x