一、为什么要进行屏幕适配

某厂商统计如下数据

  • 2012年,支持Android的设备共有3997种
  • 2013年,支持Android的设备共有11868种
  • 2014年,支持Android的设备共有18796种
  • 2015年,支持Android的设备的共有24093种
  • http://www.sfw.cn/xinwen/471726.html(2015年统计,里面包含android设备,厂家,碎片化)

二、屏幕适配对象

我们到底应该对哪些屏幕进行适配

  • 首先来看下最新的Android设备分辨率(2016年)

进行适配的还是以上的主流的几个分辨率

三、重要概念

(1)、什么是屏幕尺寸、屏幕分辨率、屏幕像素密度

屏幕尺寸
  • 屏幕尺寸指屏幕的对角线的长度
  • 单位是英寸,1英寸=2.54厘米
屏幕分辨率
  • 屏幕分辨率是指横纵向撒花姑娘的像素点数
  • 单位是px ,1px=1个像素点
  • 一般以纵像素*横向像素,如1920*1080
屏幕像素密度
  • 屏幕像素密度是指每英寸上的像素点数
  • 单位是dpi,即“dot per inch”的缩写
  • 屏幕像素密度与屏幕尺寸和屏幕分辨率有关
  • 如Nexus 5
    • 屏幕4.95
    • 1920*1080
    • 445dpi 1920^2+1080^2 进行开方 然后除以对角线长度4.95 等于445

(2)、什么是dp,dip,dpi,sp、px ?之间的关系是什么?

px
  • 构成图像的最小单位
dp 、dip
  • Density Independent Pixels的缩写,即密度无关像素
  • 以160dpi为基准,1dpi = 1px
sp
  • 即Scale-Independent Pixels
  • 可以根据文字大小首选项进行缩放
  • 绝大部分用于文字的大小推荐12sp、14sp、18sp、22sp

(3)、什么是mdpi、hdpi、xdpi、xxdpi、xxxdpi?如何计算和区分?

在新创建项目的时候,会自动创建不同的drawable或者mipmap文件夹(在不同像素密度上提供不同的图片)
或者不同的value下面(在不同像素密度提供不同的值)dimens.xml(这个放在不同的values下面)

名称 像素密度范围
mdpi 120dpi-160dpi
hdpi 160dpi-240dpi
xhdpi 240dpi-320dpi
xxhdpi 320dpi-480dpi
xxxhdpi 480dpi-640dpi

四、解决方案

支持各种屏幕尺寸

  • 使用wrap_content、match_parent、weight
   <Button  android:text="button1" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" />    <Button  android:text="button2" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" />


如果是下面的match_parent的情况

   <Button  android:text="button1" android:layout_width="match_parent" android:layout_weight="1" android:layout_height="wrap_content" />    <Button  android:text="button2" android:layout_width="match_parent" android:layout_weight="2" android:layout_height="wrap_content" />


这里就介绍一下:

  • weight
    计算出的宽度 = 原来的宽度 + 剩余空间所占百分比宽度
    假设屏幕的宽度是L
BUTTON1为例 (第二种的0dp宽度)1/3L   --> 0 + (L) * 1/3  = 1/3L
BUTTON1为例 (第二种的match_parent)2/3L   --> L + (L-2L) * 1/3  = 2/3L

通过以上的算法,就知道了为啥上面的两个图的显示大小了,同时高度也是同样的适用。

  • 使用相对布局,禁用绝对布局
    • 一般使用线性布局LinearLayout、相对布局RelativeLayout、帧布局FrameLayout,不使用绝对布局AbsoluteLayout
  • 使用限定符
    • 使用尺寸限定符(android3.2之前)
res/layout/main.xml 单面板<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /></LinearLayout>res/layout-large/main.xml 双面板   (当运行到平板的时候,就会选用下面的布局(大于7英寸))<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/>    <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /></LinearLayout>
* 使用最小宽度限定符(android3.2之后)
res/layout/main.xml,单面板(默认)布局:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /></LinearLayout>res/layout-sw600dp/main.xml,双面板布局:  Small Width 最小宽度(宽或者高最小的一边大于600dp就是用以下布局)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/>    <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /></LinearLayout>

如果适配android3.2之前,要有以上的两个维护布

* 使用布局别名
使用布局别名res/layout/main.xml:            单面板布局res/layout-large/main.xml:      多面板布局res/layout-sw600dp/main.xml:    多面板布局多面板布局共同部分抽取出来,生成main_twopanes文件res/layout/main.xml             单面板布局res/layout/main_twopanes.xml    双面板布局setContentView(R.layout.main);默认布局res/values/layout.xml:<resources>    <item name="main" type="layout">@layout/main</item></resources>Android3.2之前的平板布局res/values-large/layout.xml:<resources>    <item name="main" type="layout">@layout/main_twopanes</item></resources>Android3.2之后的平板布局res/values-sw600dp/layout.xml:<resources>    <item name="main" type="layout">@layout/main_twopanes</item></resources>
* 使用屏幕方向限定符
使用屏幕方向限定符res/values-sw600dp-land/layouts.xml:<resources>    <item name="main" type="layout">@layout/main_twopanes</item></resources>res/values-sw600dp-port/layouts.xml:<resources>    <item name="main" type="layout">@layout/main</item></resources>
小屏幕,纵向: 1.单面板
小屏幕,横向: 单面板
7 英寸平板电脑,纵向: 2.单面板,带操作栏
7 英寸平板电脑,横向: 3.双面板,宽,带操作栏
10 英寸平板电脑,纵向: 4.双面板,窄,带操作栏
10 英寸平板电脑,横向: 双面板,宽,带操作栏
电视,横向: 双面板,宽,带操作栏
1.res/layout/onepane.xml:(单面板)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /></LinearLayout>
2.res/layout/onepane_with_bar.xml:(单面板带操作栏)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">    <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1" android:gravity="center" android:layout_height="50dp">        <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/logo" android:paddingRight="30dp" android:layout_gravity="left" android:layout_weight="0" />        <View android:layout_height="wrap_content" android:id="@+id/view1" android:layout_width="wrap_content" android:layout_weight="1" />        <Button android:id="@+id/categorybutton" android:background="@drawable/button_bg" android:layout_height="match_parent" android:layout_weight="0" android:layout_width="120dp" style="@style/CategoryButtonStyle"/>    </LinearLayout>    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /></LinearLayout>
3.res/layout/twopanes.xml:(双面板,宽布局)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/>    <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /></LinearLayout>
4.res/layout/twopanes_narrow.xml:(双面板,窄布局)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">    <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="200dp" android:layout_marginRight="10dp"/>    <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /></LinearLayout>
1.res/values/layouts.xml:<resources>    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>    <bool name="has_two_panes">false</bool></resources>
2.res/values-sw600dp-land/layouts.xml:<resources>    <item name="main_layout" type="layout">@layout/twopanes</item>    <bool name="has_two_panes">true</bool></resources>
3.res/values-sw600dp-port/layouts.xml:<resources>    <item name="main_layout" type="layout">@layout/onepane</item>    <bool name="has_two_panes">false</bool></resources>
4.res/values-large-land/layouts.xml:<resources>    <item name="main_layout" type="layout">@layout/twopanes</item>    <bool name="has_two_panes">true</bool></resources>
5.res/values-large-port/layouts.xml:<resources>    <item name="main_layout" type="layout">@layout/twopanes_narrow</item>    <bool name="has_two_panes">true</bool></resources>
  • 使用自动拉伸位图
    就是.9图的使用,再此推荐一篇关于.9图的如何制作
    http://blog.csdn.net/lizzy115/article/details/7950959

支持各种屏幕密度

  • 1、使用非密度制约像素

    • 使用sp来控制文字的大小

    • 使用dp来控制布局控件的位置(这里有坑,看看下面)

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent" android:orientation="vertical">    <Button  android:layout_width="150dp" android:background="@android:color/holo_blue_dark" android:layout_height="match_parent" />    <Button  android:layout_width="200dp" android:layout_alignParentRight="true" android:background="@android:color/darker_gray" android:layout_height="match_parent" /></RelativeLayout>

由此可知,虽然我们已经使用了dp(密度无关)但是显示还是不能达到统一的效果

问题的关键所在—>各种设备的宽度不是一致的,即使使用dp,也是会有误差的。
解决思路—>不使用dp
多个values下面提供不同的dp值,(必须为每一种设备提供对应的资源文件,如果没有,就去默认的资源文件里面查找),但这个最终还是以px为单位的,这个就要自己斟酌了。
* 2、提供备用位图
* 不同的屏幕密度提供相匹配的图片
* 但是为了打包的小,一般还是一套图,一些比较重要的匹配的,可以多切几套图
* 使用和设备相符合的,使用的内存占用是最小的

实施自适应用户界面流程

  • 1、确定当前布局
  • 2、根据当前布局做出响应
  • 3、重复使用其他活动中的片段
  • 4、处理屏幕配置变化

最佳实践

  • 关于高清设计图尺寸
  • 动态设置
    • 在使用popupwindow的时候动态设置布局

更多相关文章

  1. android - 为安全而设计 - 3 - 开发文档翻译
  2. 【Android(安卓)Studio使用教程3】Android(安卓)Studio的一些设
  3. 使用Android(安卓)adb命令来启动Android应用程序
  4. android ndk 开发之 在 应用程序中使用 jni
  5. android SQLite 使用实例
  6. Kotlin让Android更简单~
  7. android ndk 开发之 在 应用程序中使用 jni
  8. android网络编程——使用Android中的网络连接
  9. Android(安卓)OpenGL教程-第一课

随机推荐

  1. 《android 学习》三、Intent 的概念及应
  2. Android Studio Mac 下卸载与安装
  3. Android 之两点触摸技术
  4. android 可编辑的下拉框 Demo
  5. Android开发插件Eclipse ADT
  6. android支付宝客户端html5网页偶尔无法自
  7. scrollTo 以及 scrollBy方法使用说明
  8. Android——XML解析
  9. Android启动模式总结
  10. android 设置静态wifi地址