android屏幕适配方案(一)

三句话适配android设备

①将(https://github.com/wenzb/ScreenAdaptive/tree/master/app/src/main/res)的values-sw320dp、values-sw360dp、values-sw431dp、values-sw480dp、values-sw540dp文件夹copy到项目res文件夹下。

②在布局文件用到dp时改成使用"@dimen/dp_**"形式,如:android:layout_width="200dp"改成android:layout_width="@dimen/dp_200"。

③在布局文件下Design选用Nexus4(4.7,768x1280,xhdpi)查看布局基准调整布局

适配原理

屏幕适配有多种方案这里选用dp适配方案,即使用不同values-sw**dp命名

sw指的是最小屏幕宽度即是手机屏幕宽度的dp值

在values的dimens.xml定义变量值引用如:<dimen name="dp_1">1.3dp</dimen>,android系统会根据屏幕的相关信息去取对应变量值

假设屏幕是属于sw360dp取出dp_1为1dp,假设屏幕属于480dp取出dp_1为1.3dp,通过这种方式从而实现屏幕适配

如何根据原理适配

android中各种单位的含义:
px:(像素) 屏幕上的小灯泡,假设是1920x1080可以理解为横向有1080个小灯泡排列
sp: scaled pixels(放大像素). 用于字体显示,会根据系统字体大小设置改变
dp(dip): (设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关
dpi:屏幕密度,每英寸(2.54cm)所含像素点,相当于ios的ppi,
density:概念跟dpi是一样,都是屏幕密度只是数值上等于dpi/160,余数不足时进0.5,假设148dpi/160 density=1 假设220dpi/160 density=1.5

dp跟dip是一样的,这个单位比较难理解但是根据运算公式:dp=px/(dpi/160) 或者是dp=px/density,dp跟像素还有屏幕密度有关,假设屏幕密度一定,当然屏幕越长或者说越多的像素dp值就增大

假设像素一定,分辨率越小dp就越大,同是假设1920x1080的6寸屏幕跟1920x1080的14寸平板,他们的屏幕长度不一样导致dpi不一样,所以根据公式可以知道这个1920x1080的14寸平板比1920x1080的6寸手机dp值大得多

谷歌提供的方案

核心是根据设备相关信息去取不同的res文件夹,如上面的例子,是根据不同sw取不同的资源文件,文件夹命名如下:
values-mcc310-en-sw320dp-w720dp-h720dp-large-long-port-car-night-ldpi-notouch-keysexposed-nokeys-navexposed-nonav-v7

属性是按优先级匹配先后排列出来的,各种含义:
values-mcc310(sim卡运营商)-en(语言)-sw320dp(屏幕最小宽度)-w720dp(屏幕最佳宽度)-h720dp(屏幕最佳高度)-large(屏幕尺寸)-long(屏幕长短边模式)-port(当前屏幕横竖屏显示模式)-car(dock模式)-night(白天或夜晚)-ldpi(屏幕最佳dpi)-notouch(触摸屏模类型)-keysexposed(键盘类型)-nokey(硬按键类型)-navexposed(方向键是否可用)-nonav(方向键类型)-v7(android版本)

假设我是横屏,屏幕是1920x1080 android系统就会去解析values-1920x1080-prot文件

同理layout文件夹也适用,所以在你开发项目的时候一定要知道你的app是会适用在哪些屏幕,如果你App运行在values-sw480dp的设备,但是你没有定义values-sw480dp文件,就会去解析相近sw-480dp的,最后都没有就会去匹配默认values

生成适配文件
public class MainActivity extends AppCompatActivity {
    DecimalFormat df = new DecimalFormat("0.0");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                saveDimens(320);
                saveDimens(360);
                saveDimens(431);
                saveDimens(480);
                saveDimens(540);
                saveDimens(768);
                saveDimens(1080);
            }
        }).start();
    }

    /**
     * 以sw360dp为基准在sd卡根目录生成对应dimens.xml 文件
     */
    private void saveDimens(int swDp){
        String str="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n";
        for (int i = 1; i <= 640; i++) {
            double a=i;
            String b=df.format(a*swDp/360);
            str+="<dimen name=\"dp_"+i+"\">"+b+"dp</dimen>\n";
        }
        str+="</resources>";

        File file=new File(Environment.getExternalStorageDirectory()+"/"+"values-sw"+swDp+"dp");
        if (!file.exists()){
            file.mkdirs();
        }

        byte[] buff=str.getBytes();
        try {
            FileOutputStream out=new FileOutputStream(file.getPath()+"/dimens.xml");
            out.write(buff, 0, buff.length);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行上面的代码,几秒后进入手机根目录copy出来放到项目。

生成文件后,布局文件如下在各个手机屏幕上的效果

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <TextView
        android:id="@+id/textView"
        android:layout_width="@dimen/dp_300"
        android:layout_height="@dimen/dp_200"
        android:background="#f4546a"
        android:gravity="center"
        android:text="你好 世界"
        android:textColor="#ffffff"
        android:textSize="30sp" />

</LinearLayout>
4.0_480x800_233dpi_hdpi_sw320.png
4.7_720x1280_312dpi_xhdpi_sw360.png
5.0_1080x1920_440dpi_xxhdpi_sw431.png
5.5_1080x1920_400dpi_xxhdpi_sw431.png
6.0_1080x1920_367dpi_xxhdpi_sw480.png
6.0_1440x2560_490dpi_xxxhdpi_sw480.png
授之于渔

是否有疑问这个320 360 431 480 540 是怎么来的?
这是目前市面上的主流手机dp值多去算算就知道了
假设android后面发展有其他奇葩或者更高清的屏幕,只需要改一下生成适配代码重新生成就可以了

同理如果要用px方案适配,生成类似values-1920x1080是一样的做法

为什么不使用px方案不是更精准吗?市面上的手机之间的px相差太大,比如480x800跟1440x2560,px适配方案可能在在不同的设备相差会几倍 ,如果处理不好布局就会大乱,而且很多奇葩分辨率,但dp就算是有问题相差也少看起来问题不大,总的来说dp设配比较稳

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

推荐阅读更多精彩内容