近来在做android屏幕适配这方面的工作, 今天总算有点眉目. 小记一下
基础知识就不科普了, 网上一大堆. 作为一个刚接触这方面人, 最先进入我脑子的, 是从小到大的各种屏, 小到手表, 大到街头上看到的广告牌. 然后对这些不同大小的屏按使用方式来区分一下:
3.5 英寸以下的. 这个尺寸以下的手机比较少, 穿戴设备比较多
3.5 - 7 英寸 这个尺寸区间主要是手机
6 英寸以下的平板. 也是比较少的
6 - 11 英寸 这个区间主要是平板
手机和平板都是拿在手上的设备(当然也可以放在支架上看), 以7英寸作为尺寸分割点. 这个分割点决定了界面的布局, 即, 小于7英寸的屏用一套布局, 大于7英寸的屏用另一套布局(因屏的大小或者横竖使用, 得用到两到四套布局)
由于项目目前只考虑在手机上使用, 所以目前就只要考虑7英寸以下的屏, 就是说, 只要写一套布局就行了. 后期要做平板的话, 再写另外的布局. 用到fragment. 这个有点离题了, 不扯这个.
layout_width & layout_height 只用match_parent.
用px显然是不行的. 同样大小的屏, 分辨率低的屏显示出来的控件大, 分辨率高的屏显示出来的控件小, 随着分辨率的差异越来越大, 控件显示出来的大小差异也越来越大.
用wrap_content也是有问题的. 现在图片资源都放在drawable-x & mipmap-x 两个目录中.
drawable放.9图片以及一些selector, corner 用来控制这些.9显示风格的.
mipmap放图片资源. 后面的-x 是指 ldpi, mdpi, hdpi, xhdpi, xxhdpi. 每个目录下面放不同像素密度的图片资源. 如果把资源都放在某一个目录下面. 比如都放在xhdpi下面, 考虑同样大小的屏(手机屏的大小差异没多少), 那么在高分辨率屏的下面显示出来的图片就比较大, 而在低分辨率屏的下面显示出来的图片就比较小, 因为android系统将xhdpi下面的图片缩小了之后再拿到低分辨率屏下面使用, 所以变小了. 好了, 那么如果这些图片资源放在lhdpi下面呢 那么在低分辨率屏下面显示出来很清晰, 但是在高分辨率屏下面显示出来就很模糊了, 因为android系统将lhdpi下面的图片放大了之后再拿到高分辨率屏下面使用. 所以图片就变大, 也就变模糊了.
如果不想android系统放大或者缩小图片, 那就用高分辨率图片直接放在mipmap目录下面吧.
还是考虑差不多大小的手机屏, 不同的分辨率以及不同的长宽比. 其实对于长宽比固定的分辨率, 如果在布局文件中都是使用相对布局, 那么布局不会发生改变. 剩下的就是要考虑到长宽比不一样的分辨率了.
比如说一些常见的分辨率. {640*360} {960*540} {1280*720} {1920*1080} {2560*1440} 这几个分辨率的长宽比都是1.7777....
{1280*768} {800*480} 这两个长宽比是1.666...{1280*800} {2560*1600} 这两个长宽比是1.6
对于这些乱七八糟的长宽比, 同样的布局显示出来的效果就会有拉伸的效果了. 因长宽比值大小而决定拉伸效果.
后来就想用dimens来写不同分辨率下面对应的px, 然后在布局中直接使用dimens, 这样在不同的机型上面会用到不同的数值. 从而适配不同长宽比的屏. 但是这样做有两个问题. 一是这样的dimens太多,难以维护,就算做了主流的分辨率, 遇到一个分辨率未设置dimens的手机,显示出来的效果就非常糟糕. 二是有些手机它下面的那一排控制按钮是用软件实现的, 不是直接做在硬件上面的. 这就对界面的分辨率生产了影响.
从3.0以后, 对于要适配1280*720这样分辨率的屏, 之前的写法是写一个layout-1280x720这样的文件夹, 里面放置对应的dimens文件. 而现在要减去一个48px(状态栏的高度), 文件夹的名称就要写成layout-1232*720, 然后里面放置dimens文件, 但是我测试了一些机器发现读取不到这个文件, 找了一下问题, 发现不同的系统状态栏的高度是不一样的, 如果还要使用这样的解决方案的话, 那得先解决状态栏不一样高这个问题. @[email protected]!!! 其实可以在values/dimens.xml中来设置这个状态栏高度, 不过我测试.
其实问题的根源就是控件无法在长宽上面设置相对的百分比. 然后想到了扩展控件修改自绘, 添加相对百分比的属性. 这样一想, 就先到网上找找有没有人 有过同样的想法并实现了的, 还真有! 参考下面的链接:
http://blog.csdn.net/lmj623565791/article/details/46767825
下面就是使用这个库了. 在使用的问题遇到一个问题:
Error:Execution failed for task ‘:app:dexDebug‘.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:\Program Files\Java\jdk1.7.0_79\bin\java.exe‘‘ finished with non-zero exit value 2
这个问题是由于库冲突. 那只要把冲突的库排除了就可以了.
先在gradle.build中把这个库给注释掉
编译运行一下, 没有问题. 打开ProjName/.idea/libraries, 把这个目录下面的文件截个图保存一下(用来对比看看多了哪个库). 然后把gradle.build中的引用库注释取消. 再编译, 出现上面的问题, 再打开ProjName/.idea/libraries 看看这时候目录下面跟刚才相比多了几个文件, 如下图, 多了三个文件:
第一个文件是库的引用, 在gradle.build中把下面的两个文件删除即可, 如下图
再运行, OK, 没问题了.