Android适配

学之广在于不倦,不倦在于固志。 ——晋·葛洪­

(学问的渊博在于学习时不知道厌倦,而学习不知厌倦在于有坚定的目标)

001.至于Android适配网上各位大牛各显其招,我这里copy一份鸿洋大神的一份:

      --->相关概念:

            >>> 屏幕尺寸:指屏幕的对角线长度,单位是英寸,1英寸=2.54cm;

            >>> 屏幕分辨率:指在纵横方向上的像素点数,单位是px,1px=1个像素点。一般屏幕分辨率是纵向像素点*横向像素点,如1280*720

            >>> 屏幕像素密度:指每英寸上的像素点数,单位dpi,即"dot pre inch"的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小屏幕分辨率越高,像素密度越大,反之越小

            >>> dip和dp:两者是同一个东西,都是"Density Independent Pixels"的缩写,即密度无关像素

                   密度无关像素分析:

                           1).假如1英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,由于在Android中,规定以160dpi为基准,1dp=1px;如果屏幕像素密度是360dpi,则1dp=2px;以此类推计算可以得出所有的dp值

                           2).例如同样划一条320px的线,在480*800的分辨率的手机上显示为屏幕的2/3宽度,在320*480的手机上则占满了全屏,如果使用dp作为单位,在这两种分辨率下,160dp都是显示屏幕一半的长度,因此,我们在布局中需要把单位设置为dp,谷歌官方也要求写成dp

              >>> sp:"scale-independent pixels"的缩写,与dp类似,但是可以根据文字的大小首选项进行缩放,标准字体单位

    ---> 引入百分比适配:

           >>> 经过上面的分析我们知道,为了规避不同像素密度带来的适配问题,谷歌官方推荐使用dp来代替px作为控件长度的度量单位,但是,我们来看一个场景,假如我们以Nexus5作为书写代码时查看效果的测试机型,Nexus5的总宽度为360dp(可以通过上面的分析得出),我们现在需要在水平方向上放置两个按钮,一个是150dp左对齐,另一个是200dp右对齐,中间留有10dp的间隔,在Nexus5上面显示是正常的;但是在NexusS或者NexuOne上显示就不正常了,两个按钮发生了重叠

                        分析原因:dp虽然可以去除不同像素密度的问题,使得1dp在不同的像素密度上显示效果是相同的,但是,由于Android屏幕设备的多样性,如果使用dp来作为度量单位,并不是所有的屏幕宽度都是相同的dp长度,比如说,NexusS和NexusOne同属于hdpi,屏幕宽度是320dp,而Nexus5属于xxhdpi,屏幕宽度是360dp,Galaxy Nexus属于xhdpi,屏幕宽度是384dp...

                        所以说,谷歌自己一家的产品(Nexus系列)就已经有这么多的标准,而且屏幕宽度和像素密度没有任何关联关系,即使我们使用dp,在320dp宽度的设备上和384dp的设备上,还是会有64dp的差别。由此就导致了上面显示问题!

           >>> 基于上面的问题,我们就采取一种方法来统一单位,不管分辨率是多大,屏幕宽度用一个固定的值的单位来统计,于是,百分比适配就产生了:

                 我们自定义一个标准(以UI切图的分辨率,比如1280*720),我们就假设手机屏幕的宽度都是720px,那么我们将一个屏幕宽度的总像素平均分成720份,每一份对应1个像素值(即1px),哈哈,这样就满足了适配...

     ---> 这份代码是copy鸿洋大神的,略加修改,因为我们UI是基于1280*720切的图,不建议做这么多分辨率的适配(体积会增大许多),我只是测试时用的这么多

/**

* Created by Okamiy on 2018/5/7.

*/

public class ScreenUtils {

private final static StringrootPath ="C:\\Users\\Administrator\\Desktop\\layoutroot\\values-{0}x{1}\\";

    private final static float dw =720f;

    private final static float dh =1280f;

    private final static StringWTemplate ="{1}px\n";

    private final static StringHTemplate ="{1}px\n";

    public static void main(String[] args) {

makeString(480, 854);

        makeString(480, 800);

        makeString(540, 960);

        makeString(720, 1184);

        makeString(720, 1208);

        makeString(720, 1280);

        makeString(720, 1440);

        makeString(752, 1280);

        makeString(1080, 1776);

        makeString(1080, 1788);

        makeString(1080, 1794);

        makeString(1080, 1800);

        makeString(1080, 1808);

        makeString(1080, 1812);

        makeString(1080, 1920);

        makeString(1080, 2160);

        makeString(1080, 2280);

        makeString(1440, 2560);

        makeString(1440, 2960);

    }

public static void makeString(int w, int h) {

StringBuffersb =new StringBuffer();

        sb.append("\n");

        sb.append("");

        float cellw = w /dw;

        for (int i =1; i <720; i++) {

sb.append(WTemplate.replace("{0}", i +"").replace("{1}",

                    change(cellw *i) +""));

        }

sb.append(WTemplate.replace("{0}", "720").replace("{1}", w +""));

        sb.append("");

        StringBuffersb2 =new StringBuffer();

        sb2.append("\n");

        sb2.append("");

        float cellh = h /dh;

        for (int i =1; i <1280; i++) {

sb2.append(HTemplate.replace("{0}", i +"").replace("{1}",

                    change(cellh *i) +""));

        }

sb2.append(HTemplate.replace("{0}", "1280").replace("{1}", h +""));

        sb2.append("");

        Stringpath =rootPath.replace("{0}", h +"").replace("{1}", w +"");

        FilerootFile =new File(path);

        if (!rootFile.exists()) {

rootFile.mkdirs();

        }

FilelayxFile =new File(path +"lay_x.xml");

        FilelayyFile =new File(path +"lay_y.xml");

        try {

PrintWriterpw =new PrintWriter(new FileOutputStream(layxFile));

            pw.print(sb.toString());

            pw.close();

            pw =new PrintWriter(new FileOutputStream(layyFile));

            pw.print(sb2.toString());

            pw.close();

        }catch (FileNotFoundException e) {

e.printStackTrace();

        }

}

public static float change(float a) {

int temp = (int) (a *100);

        return temp /100f;

    }

}

    ---> 直接运行即可生成对应的分辨率文件

          注意:

                    ---> 必须再给values下面来一份lay_x.xml和lay_y.xml,因为对于没有生成对应分辨率文件的手机,会默认使用values文件夹下面的,如果没有就会报错无法适配。

                     ---> values文件夹下面的lay_x.xml和lay_y.xml里面的单位要改为dp,切记,因为不知道机型的分辨率,所以采用dp能更好的适配(此处lay_x.xml和lay_y.xml的算法,应该是根据UI出图的标准分辨率来转化为dp,比如:我们的UI是1280*720,此时1px=0.5dp,换算关系见下图。这样计算的好处也是更好适配我们没有的分辨率,因为我们项目里面的尺寸都是安装UI切图的这个基准来标注的)。

                            在Android中,规定以160dpi(即480*320)为基准:1px=1dp;

    密度类型               代表的分辨率(px)  屏幕密度(dpi)   换算(px/dp)    比例

 低密度(ldpi)                240x320                     120                 1dp=0.75px          3

 中密度(mdpi)              320x480                     160                 1dp=1px               4

 高密度(hdpi)               480x800                      240                1dp=1.5px            6

 超高密度(xhdpi)          720x1280                   320                 1dp=2px               8

超超高密度(xxhdpi)    1080x1920                   480                1dp=3px               12

              在values下面的文件:

002.使用特别简单:

    根据UI给的图进行编写layout.xml文件即可,根据标注的尺寸设置给控件即可,是多少px就写多少px

003.Android适配要学的还很多,这里推荐几个很棒的博文,本文也是提取这几篇博文相关内容整理而成:

      鸿洋:Android 屏幕适配方案

      郭霖:Android官方提供的支持不同屏幕大小的全部方法

      赵凯强:Android屏幕适配全攻略(最权威的官方适配指导)

    Last.欢迎指正、交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容