dpi适配android_android dpi适配 - CSDN
  • 上次我们讲了DPI,分辨率的一些事儿(有兴趣的童鞋可以去这里看:android屏幕适配终极指南(一):DPI,分辨率和屏幕尺寸)这次我们来讲点跟android有关的。 大家都知道,一个正常的工程,都会有如下几个文件夹: ps...

    上次我们讲了DPI,分辨率的一些事儿(有兴趣的童鞋可以去这里看:android屏幕适配终极指南(一):DPI,分辨率和屏幕尺寸

    这次我们来讲点跟android有关的。
    大家都知道,一个正常的工程,都会有如下几个文件夹:
    这里写图片描述

    ps:旧的版本还会有个drawable-ldpi,也就是low dpi,但是这个在我现在使用的android studio1.0中,创建工程时并没有生成它,我猜测可能是现在的手机基本上不会有ldpi,所以默认不生成这货了。

    这几个文件夹是干啥的,我相信各位也知道:不同分辨率下的图片资源放在不同的文件夹下面,来保证不同分辨率下的图片不会变形

    我相信你们也在网上找到过各种资料,对这几个文件夹有过如下的描述:

    drawable-ldpi: 对应分辨率240*320
    drawable-mdpi: 对应分辨率320*480
    drawable-hdpi: 对应分辨率480*800
    drawable-xhdpi: 对应分辨率720*960
    drawable-xxhdpi:对应分辨率720*1280

    也就是说,我给一个按钮出5张不同分辨率的图,分别放在这5个文件夹下面,这样手机分辨率就算不一样,按钮也不会变形或者模糊什么的。
    那么问题来了,如果我的手机分辨率是500*800,那么它属于哪个?
    有人说hdpi,因为最相近,有人说xhdpi,因为超过hdpi的最高值了,其实哪个都有可能,还有可能是xxhdpi呢

    所以上面的公式实际上是不对的,或者说,它只是一个通常状况下的公式,但是国内手机生产商什么样的奇葩手机都能生产出来,你还指望有什么”通常状况”。。。

    真正的公式如下:

    drawable-ldpi (dpi=120, density=0.75)
    drawable-mdpi (dpi=160, density=1)
    drawable-hdpi (dpi=240, density=1.5)
    drawable-xhdpi (dpi=320, density=2)
    drawable-xxhdpi (dpi=480, density=3)

    也就是说,这5个文件夹,关联的不是分辨率,而是DPI
    后面那个density,通常我们叫它”密度因子”。它的计算公式是:DPI/160 = density,是的,你没有看错,就是一个固定值160。为啥要选160呢?
    这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的。

    The generalized sizes and densities are arranged around a baseline
    configuration that is a normal size and mdpi(medium) density. This
    baseline is based upon the screen configuration for the first
    Android-powered device, the T-Mobile G1, which has an HVGA screen
    (until Android 1.6, this was the only screen configuration that
    Android supported).

    既然说到了density,那我们就要提一提dp

    相信每个开发者都不会陌生,我们在绝大多数情况下,给布局文件里面的控件定义尺寸,都不会直接使用px,而是使用dp:

        <WebView
            android:id="@+id/webview"
            android:layout_width="200dp"
            android:layout_height="100dp"/>

    先看看dp的概念:dp,又叫dip(density independent pixel),独立密度像素。
    这么解释基本上等于废话,我们来举例说明:
    假设现在没有dp,只有px。现在我们在程序中要画一条线,这条线的长度是屏幕宽度的一半。
    正好你手头的测试机是320*480的,那你就在代码里写了这条线的长度如下:

    <ImageView
            android:id="@+id/line"
            android:layout_width="160px"
            android:layout_height="1px"/>

    160px,正好等于屏幕宽度的一半。
    然后你换一个480*800的手机测试一下吧。
    我擦,怎么这条线只占屏幕的1/3了!
    很正常,因为你画的线是160px,而在480px的手机上,160/480=1/3
    那咋办。。。。
    我判断一下,如果手机是480的,我就把width改成240。
    那我再换个别的尺寸,你还要改,而且你根本不知道明天会冒出一个什么新的尺寸的手机来。。。。

    所以为了减少开发者的工作量,Google提出了dp的概念,dp和px之间的换算公式是:

    px = dp * (dpi / 160) = dp * density

    ok,现在我们再回到画直线的问题.
    我的屏幕是320*480的,所以我的线的长度应该是160px,320*480的分辨率,通常dpi=160,所以也就是 dp = px/(dpi / 160) = 160/(160/160) = 160
    现在再拿刚才480*800的手机过来,通常480*800的手机dpi=240,所以代入刚才的dp=160,我们可以得到px=dp * (dpi/ 160)=160*(240/160)=240;也就是说,在 480*800且dpi=240的手机上,线的长度为240px,正好也是屏幕的一半。

    你们看,问题现在解决了吧?
    其实并没有,你换个别的手机,比如720*1280且dpi=480的试试,你发现还是不等于1/2!!!

    咋办?
    不咋办,就是这样,如果你要实现一半长的线,应该用别的方法,而不是dp。

    所以上面的例子,我主要是要告诉大家,为啥要有dp
    **

    因为在通常情况下,用dp能省去开发者很大的工作量

    **

    但是,你也看到了,dp并不能解决所有问题,好在我们绝大部分情况下,不需要画一半的直线,我们更通常的情况,是摆放一个按钮,然后指定这个按钮的尺寸:

    <Button
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="100dp"/>
    

    在不同的分辨率和dpi的手机上,这个按钮有时候是按照我们预想的大小比例来显示的,有时候则不是,会整体稍小一点,有时候也会整体偏大一点。好在大部分情况下,我们并不在意这一点偏差,所以你看,dp还是可以解决很多问题的。

    那如果真的在意这一点偏差呢?或者偏差比我们预想得要大呢?
    卖个关子~那就是我们下一讲的问题了,哈哈~

    展开全文
  • 机型适配: 作用是使应用程序能够在广泛的软件系统和硬件平台上都可以正常的稳定的运行 操作系统的版本的适配。API android 上面的手表,平板电脑, 所有做客户端的必须要做机型适配 机型适配的要求: 匹配,合适,...

    最重要的适配就是尺寸适配,我们可以有两种方案:


    第一种方案,以某一个尺寸,例如1920*1080为基准的,在文件中修改 http://blog.csdn.net/lmj623565791/article/details/45460089
            int baseW = 1080;
            int baseH = 1920;
    然后生成相应的其他的尺寸的dimen文件
    这种的优点就是:可以直接根据美工的图来输入相应的数字就好了,然后一切都会自动的计算好的,当然美工的图的尺寸和我们的基准尺寸要是一样的
    缺点就是有一些没有考虑到的尺寸会有一点问题,软件会较大


    第二种方案,百分比的利用。http://blog.csdn.net/lmj623565791/article/details/46695347
    这个方法很完美,可以解决上面没有考虑到尺寸的问题,还有软件较大的问题。
    缺点:但是需要自己计算一次比例。


    第三种方案,就是两者相结合。


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++




    屏幕像素密度
    屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。
    一英寸是2.54cm就是一英寸的照片的对角线。像我们的收银机就有xdpi ydpi就是横竖的dpi是不同的。

    记住一个点就是dp 是密度无关的。

    dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。


    最关键的就是图片适配和尺寸适配,
    图片适配,我们一般是,其实就是5张图片。

    mdpi就是1倍	160dpi		480*320		2*2
    hdpi就是1.5倍	240dpi		800*480		3*3	小手机
    xhdpi就是2倍	320dpi		1280*720P	4*4
    xxhdpi就是3倍	480dpi		1920*1080P 	6*6	大手机
    xxxhdpi就是4倍	640dpi		2k的屏幕的适配	8*8




    规则是,如果241dpi,那么就调用320dpi的图片来做。


    我们可以按照手机屏幕的标准把800×480理解为hdpi,480×320为mdpi,320×240为ldpi,根据最新的数据显示,Android所有手机中hdpi和mdpi占

    有九成以上的比例;还有1280×720、1920×1080等高分辨率的android手机界面。


    尽量使用wrap_content match_parent 和权重,如果要用那么就是使用宽度适配的方式


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    尺寸适配,现在一般都是使用的,使用了权重以后,可以使用百分比来进行适配。
    最小边适配,宽度适配,高度适配。
    在弘扬的博客中,也有将px进行转换的一些操作。
    w511dp 就是宽度适配,h600dp就是高度适配,sw600dp就是最小边适配


    百分比首先要导入包:

    compile 'com.android.support:percent:23.4.0'

    现在直接用hongyang的compile 'com.zhy:percent-support-extends:1.1.1'

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
    
        defaultConfig {
            applicationId "tech.androidstudio.percentlayout"
            minSdkVersion 17
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.4.0'
        compile 'com.android.support:percent:23.4.0'
    }
    


    布局里面:

    百分比里面可以是小数点的。例如58.88%也是可以的



    <?xml version="1.0" encoding="utf-8"?>
    <android.support.percent.PercentRelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="tech.androidstudio.percentlayout.MainActivity">
    
        <TextView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:text="20%w,%20h"
            android:gravity="center"
            android:textSize="13sp"
            android:textColor="@android:color/white"
            android:background="@android:color/holo_red_dark"
            app:layout_widthPercent="20%"
            app:layout_heightPercent="20%"
            />
        <TextView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:text="80%w,%20h"
            android:gravity="center"
            android:textSize="13sp"
            android:textColor="@android:color/white"
            android:layout_alignParentRight="true"
            android:background="@android:color/holo_blue_dark"
            app:layout_widthPercent="80%"
            app:layout_heightPercent="20%" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:text="100%w,%20h"
            android:gravity="center"
            android:textSize="13sp"
            android:textColor="@android:color/white"
            android:layout_alignParentBottom="true"
            android:background="@android:color/holo_purple"
            app:layout_widthPercent="100%"
            app:layout_heightPercent="20%"/>
    </android.support.percent.PercentRelativeLayout>
    



    ++++++++++++++++++++++++++++参考++++++++++++++++++++++++++++++++
    Android 6.0 = API Level 23
    Android 5.1.1 = API Level 22
    Android 5.0.1 = API Level 21 ++++++++++++我的手机
    Android 4.4W (L) = API Level 20
    Android 4.4.2 = API Level 19++++++++++++++++我们的收银机
    Android 4.3 = API Level 18
    Android 4.2-4.2.2 = API Level 17
    Android 4.1-4.1.1 = API Level 16
    Android 4.0.3-4.0.4 = API Level 15
    Android 4.0-4.0.2 = API Level 14
    Android 3.2 = API Level 13
    Android 3.1.x = API Level 12
    Android 3.0.x = API Level 11
    Android 2.3.3+ = API Level 10
    2.2 v8 
    2.1 v7
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    







    需要添加的部分:屏幕适配部分,需要把dp,dpi这些概念再看看。


    1: 机型适配的目的就是能够使应用程序能够在绝大多数的手机上面稳定的正常的运行 
    要求是,匹配,合适,正常和稳定。
    机型适配主要分为:版本的适配(Build.VERSION),屏幕适配(手机和平板,不同的分辨率的手机),语言国家适配(阿拉伯国家),硬件适配(


    前置摄像头,后置摄像头)
    而我们 平时将的适配,主要是屏幕适配:


    版本的适配:要保证在android 的不同版本上面都能够正常的稳定的运行。
    ++++++++++++++++++++++++++++++++++++++++++++++
    例如android V6里面的动态权限请求.requestPermission.
     
    例如如果我们用到了btn.setX()的方法那么我们首先要通过Build.VERSION.SDK_INT>=11 来判断是否可以使用。
    if (Build.VERSION.SDK_INT >= 11) {
                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, linkUrl);
                } else {
                    task.execute(linkUrl);
                }


    =========================================================================
    屏幕适配:主要包含了图片适配,界面横竖屏适配,屏幕宽度高度大小适配,
    关于图片适配,因为android 会自动的根据屏幕来使用相应的图片,我们一般会请美工做lhdpi,hdpi,xhdpi,xxhdpi,xxxhdpi,实在不行的话,


    就是做两个hdpi和xxhdpi这两个,因为android 会自动的进行图片的转换。
    关于横竖屏的适配,首先创建一个layout-land的文件夹,我们可以单独的给竖屏创建一个布局,这个布局名称必须要和正常的竖屏里面的名称一样


    。这个时候切换横屏的时候就可以使用这个布局了。
    关于屏幕宽度和高度大小适配,我们选择使用dp和权重结合的方式来进行,文字的大小上面使用sp单位。然后测试几个手机上面是否显示是正常的


    。就可以了。
    =========================================================================
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    语言适配,可以直接的添加一个文件values-zh
    右键res文件,选择创建文件夹,然后选择-》values,在里面找到Locale-》点击“》”,然后就可以选择语言了。
    这里面也可以自己直接创建,如果自己知道语言的缩写的话,例如中文就是values-zh


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    硬件的适配:例如我们要开发一个罗盘应用 ,首先 要判断是否有罗盘这个感应器。没有的话,就提醒用户不能使用。




















    版本的适配:例如我们的线程池的时候的时候在版本
    ++++++++++++++++++++++++++++++++++++++++++++++
    例如android V6里面的动态权限请求.requestPermission. 
    例如如果我们用到了btn.setX()的方法那么我们首先要通过Build.VERSION.SDK_INT>=11 来判断是否可以使用。
    if (Build.VERSION.SDK_INT >= 11) {
                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, linkUrl);
                } else {
                    task.execute(linkUrl);
                }


    ++++++++++++++++++++++++++++参考++++++++++++++++++++++++++++++++
    Android 6.0 = API Level 23
    Android 5.1.1 = API Level 22
    Android 5.0.1 = API Level 21
    Android 4.4W (L) = API Level 20
    Android 4.4.2 = API Level 19
    Android 4.3 = API Level 18
    Android 4.2-4.2.2 = API Level 17
    Android 4.1-4.1.1 = API Level 16
    Android 4.0.3-4.0.4 = API Level 15
    Android 4.0-4.0.2 = API Level 14
    Android 3.2 = API Level 13
    Android 3.1.x = API Level 12
    Android 3.0.x = API Level 11
    Android 2.3.3+ = API Level 10
    2.2 v8 
    2.1 v7
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    android api向来是高版本兼容低版本.
    如api-8(android2.2)必会兼容api-4(android 1.6)
    但是反之则不会,你使用2.2的平台版本build了一个apk,若想能在1.6上运行,则需要做向下兼容.
    android support-xx是google官方的向下兼容包.
    如名所示,会帮助构建程序向下兼容到1.6版本.不过也并非万能的,还是会受限制.
    上面的 解释很正确 ,但是我们平时使用的多是v4,v7包,如果是这个是11里面的呢?例如btn.setX,task.executeOnExecutor().
    这样对于,版本是10的东西,就不能够使用了,那么 就要判断了。




    Android 版本的适配:
    1:使用Android support 包,实现高版本API的兼容;
    ActionBar就是v7包的,Fragment 是v4包
    2:通常由于采用一些新的API兼容包,那么软件最低支持Android 2.1就是API7
    3:确认软件最低支持版本的时候,需要分析使用API最低支持到那个版本;


    例如如果设置最低的版本是9
    现在设置一个
    Button btn=null;
    btn.setX(34);


    Develpe-》Reference-》API level




    版本适配:
    1:确定最低版本,不要调用最低版本以上的任何代码
    2:如果调用的高版本方法,有对应的低版本的代替
    例如View.setX()高版本,可以使用View.setLeft+View.setRight()这种低版本方法,代替
    那么就可以通过代码来进行倒台的适配;
    android.os.Build 这个类,就可以获取当前手机的各种信息,包括version
    Button btn=null;
    if(Build.VERSION.SDK_INT>=11){
    btn.setX(34);
    }else{
    Toast.....("您的手机不支持。。。")
    }


    if (Build.VERSION.SDK_INT >= 11) {
                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, linkUrl);
                } else {
                    task.execute(linkUrl);
                }


    ++++++++++++++++++++++++++++参考结束++++++++++++++++++++++++++++++++


    =========================================================================
    屏幕适配:主要包含了图片适配,界面横竖屏适配,屏幕宽度高度大小适配,
    关于图片适配,因为android 会自动的根据屏幕来使用相应的图片,我们一般会请美工做lhdpi,hdpi,xhdpi,xxhdpi,xxxhdpi,实在不行的话,


    就是做两个hdpi和xxhdpi这两个,因为android 会自动的进行图片的转换。
    关于横竖屏的适配,首先创建一个layout-land的文件夹,我们可以单独的给竖屏创建一个布局,这个布局名称必须要和正常的竖屏里面的名称一样


    。这个时候切换横屏的时候就可以使用这个布局了。
    关于屏幕宽度和高度大小适配,我们选择使用dp和权重结合的方式来进行,文字的大小上面使用sp单位。然后测试几个手机上面是否显示是正常的


    。就可以了。
    =========================================================================




    参考:
    ldpi (low) ~120dpi
    mdpi (medium) ~160dpi
    hdpi (high) ~240dpi
    xhdpi (extra-high) ~320dpi
    xxhdpi (extra-extra-high) ~480dpi
    xxxhdpi (extra-extra-extra-high) ~640dpi


    选择竖屏:
    右键res,选择directory
    resoure type 选择layout
    选择下面的Orientation 》》
    选择Screen orientation
    选择Land。。
    就会有一个文件夹layout-land


    进行机型适配,主要是在res目录
    1:图片适配屏幕DPI
    2:界面横竖切换适配
    3:屏幕宽度高度大小适配




    res文件夹的命名规则:
    resource name-修饰符
    mipmap-xhdpi








    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    语言适配,可以直接的添加一个文件values-zh
    右键res文件,选择创建文件夹,然后选择-》values,在里面找到Locale-》点击“》”,然后就可以选择语言了。
    这里面也可以自己直接创建,如果自己知道语言的缩写的话,例如中文就是values-zh


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    硬件的适配:例如我们要开发一个罗盘应用 ,首先 要判断是否有罗盘这个感应器。没有的话,就提醒用户不能使用。


    硬件适配:
    1:只有在清单文件会有这个要求,应用市场里里面,我们的清单文件会有作用的
    应用市场软件需要使用那些硬件,在清单文件声明;是否是必须的;


    2:应用市场会根据手机的特性,显示对应的软件,根据清单文件,过滤不支持的程序。
    Trainning->Supporting Different Devices


    <uses-feature android:name="android.hardware.camera" android:required="true"/>




    SensorManager sensorManager =(SensorManager)getSystemService(SENSOR_SERVICE);
    Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROTER);






    广渠门 西单商场正对面  皂君庙 西坝河 远大路 '




    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    版本适配 
            //获取panel的高度
            int height = panel.getHeight();
            //设置缩放的中心点是右侧的中点
            mContent.setPivotX(0);
            mContent.setPivotY(height/2);


            //设置缩放的等级
            mContent.setScaleX(1-slideOffset);
            mContent.setScaleY(1-slideOffset);




    //如果要兼容2.0的手机,2.0就是API5,2.1是API 7,2.3是API 9
    //        http://blog.csdn.net/rodulf/article/details/50743187


    //        ViewCompat.setPivotX(mContent, 0);
    //        ViewCompat.setPivotX(mContent, height / 2);
    //        ViewCompat.setScaleX(mContent, 1 - slideOffset);
    //        ViewCompat.setScaleY(mContent, 1 - slideOffset);




    硬件适配 :
    例如下载的路径默认是外部存储的位置,如果有没有存储卡 ,那么就是内部的存储的位置。


    if(Environment.MEDIA_MOUNTED.equals(state)){
                // MEDIA_MOUNTED 代表存储卡可用, MOUNTED 称作 "挂载"
     // 获取外部存储中,应用程序共享的目录, 返回内容可能不存在


    机型适配:

    作用是使应用程序能够在广泛的软件系统和硬件平台上都可以正常的稳定的运行
    操作系统的版本的适配。API
    android 上面的手表,平板电脑,
    所有做客户端的必须要做机型适配

    机型适配的要求:
    匹配,合适,正常,稳定。
    需求:
    1:支持Android2.1以上的版本,V7包
    2:支持手机和平板电脑,屏幕适配
    3:为阿拉伯国家提供软件,阿拉伯国家的文字为从右向左
    4:为中国移动提供软件,wmwap
    5:需要做一个拍照软件,前置摄像头,后置摄像头
    6:发布到各种软件市场,小米市场上,软件的扉页必须要有小米的标志




    如何进行机型适配(主要讲解屏幕适配)


    进行机型适配,主要是在res目录
    1:图片适配屏幕DPI
    2:界面横竖切换适配
    3:屏幕宽度高度大小适配
    4:语言适配


    res文件夹的命名规则:
    resource name-修饰符
    mipmap-xhdpi
    values-zh




    选择竖屏:
    右键res,选择directory
    resoure type 选择layout
    选择下面的Orientation 》》
    选择Screen orientation
    选择Land。。
    就会有一个文件夹values-land




    android 优先选择运营商,国外的手机在中国可能默认的就是英文的。
     
    values/strings.xml
    values-zh/strings.xml
    values-zh_rTW/strings.xml  r代表region




    屏幕适配:


    Android 提供了自动的设备检测功能,能够根据当前设备,自动的使用合适的图片。
    -------------------------------------------------------------------------------------------------------
    重点:美工给我们几套图。
    答:可以直接给一个xhdpi的图片和一个xxxhdpi的图片,或者所有的图片都给出来。前提是我们自己计算一下尺寸大小。
    -------------------------------------------------------------------------------------------------------
    例如红米2手机分辨率是720*1280,尺寸大概是2.3英寸*4英寸的,那么dpi 就是xhdpi就是320,
    那么如果我现在有一张图片在这个上面显示的是。宽度的3分之一,高度的四分之一,
    那么这个xhdpi图的大小是240px*220px。
    那么我会在要一个xxxhdpi的就是480*440的图片。
    ------------------------------------------------------------------------------------------------------
    之前是160px是标准的
    但是我们开发的时候还是要以320px的为基准比较好。也就是说以手机尺寸为720*1280的为基准的,例如红米2
    ------------------------------------------------------------------------------------------------------
    那么屏幕的dp到底多少呢?


    例如红米的屏幕分辨720*1280  dpi为2,
    屏幕的dp大小为:360dp*640dp这个就是屏幕的dp. 这个其实也就是正常的屏幕的dp值了吧。


    ------------------------------------------------------------------------------------------------------




    美工在出图的时候是按照像素单位来出图的。
    dpi:每一个手机,都有自己的硬件的屏幕参数dpi,
    一英寸能够显示多少像素。一英寸是多少呢?1英寸(in)=2.54厘米(cm),最简单就是一寸照片的底部就是一寸长的。


    通常第三个适配的时候,设计不同的dpi的图片,例如
    100px,240px,两张图片。名字都一样放在不同的mipmap或者是drawable下面


    dp虚拟的单位:dp以dpi为参数的单位,
    公式:1dp=多少个px?    px=(dpi/160)*dp


    那么5dp=?px 例如mdpi=160, 5dp-> (160/160)*5=5px
                 例如hdpi=240   5dp-》(240/160)*5dp=7.5px;
        例如xhdpi=320  5dp-> (320/160)*5dp=10px;


    总屏幕大小是多少dp呢?
    ------------------------------------------------------------------------------------------------------
    那么屏幕的dp到底多少呢?


    例如红米的屏幕分辨720*1280  dpi为2,
    屏幕的dp大小为:360dp*640dp这个就是屏幕的dp.
    但是不同的机器的 屏幕的dp值也不一样,例如红米的2的变成了更大的尺寸,但是屏幕的分辨率,没有变的话,那么dp就不会变。如果,尺寸没变,但是分辨率变大了,那么dp就会变化。
    dp=(dpi/160)px


    在xml里面预览的左上角:有一个文件标志下面有一个机器人的,
    点击后选择 Preview reprentation Sample
    可以查看相同的dp值在不同的手机上面的变化。


    ------------------------------------------------------------------------------------------------------


    注意在代码中如果没有标示就都是px的。
    ----------------------------------------


    标准是以mdpi为一准


    ldpi 120   0.75x
    mdpi 160   1x 最早的手机160个像素一英寸。
    hdpi 240   1.5x
    xhdpi 320   2x
    xxHDPI 480  3x
    xxxHDPI 640 4X


    现在软件的切换都建议采用xhdpi进行设计,然后其余的进行缩放
    采用高清大图来进行设计,切图进缩放,




    Pure Android
    Devices and Displays
    ==============================================================
    关于hdpi:
    1:在不同的dpi目录,设置同名的图片,根据缩放比例,
    进行图片尺寸的设置。在小尺寸的手机上,显示的内容尽量调整清晰。
    在大尺寸图片上面,调整图片的细节,让图片显示的内容更多,


    2:相当于程序能够同时支持 普通手机和高清版;


    3:因为android系统如果没有设置小屏幕(低dpi的图片)的图片的画,
    那么Android 就会把大图进行缩小,这个是可以的。匹配低密度的手机


    如果一个图片只有xhdpi的版本,那么在小手机上面自动缩小,这个是不会影响效率
    如果一张hdpi的图片,运行在高密度的手机上面,例如xxxhdpi手机上面,那么这张图片就会自动的进行放大。就会失帧了。
    因此建议准备多套图片,适配各种密度,


    ---------------------------------------------------------------
    ---------------------------------------------------------------
    那么我们就是要先计算出mdpi的尺寸然后和美工要这几个版本的。提供尺寸的大小。
    或者直接要一个xxxhdpi的。


    一般是要以xhdpi的图片,以这个为基准去做要图。
    大图往小图缩小细节就没有了。




    如果设置ImageView 设置
    width=100dp
    height=100dp


    在不同的手机和屏幕上面显示所在屏幕的百分比不一样


    Android 尺寸适配+++++++++++++++++++++++++++++++++++++++
    1:Android 控件,布局对于尺寸,如果在布局中固定设置xxxdp数值,在不同的手机上,虽然能够缩放
    但是和我们的预期的设置会有差别;
    2:如果能够使用wrap_content,match_parent,那么尽量使用,这样避免了实际的数字
    3:尽量使用权重layout_weight,
    4:如果需要使用固定的数值;那么需要正对数值进行适配。那么需要根据手机的屏幕尺寸,进行不同的适配将尺寸定义成一个资源。
    让android 系统,自己去进行不同的


    android 空间必须是dp,字体必须是sp,因为这样可以自动的适配


    在尺寸资源100dp这里alt+回车


    在res 里新建新的资源目录
     选择size
    选择small
    最后创建出来一个values-small
    然后依次创建normal,larget,xlarge




    +++++++++++++++++++++++++++++++++++++++
    Android 3.0以后觉得large这些划分太麻烦了
    Android
    1:提出了根据屏幕尺寸进行适配的方式;
    2:新的适配采用dp单位的宽高进行适配;
    3:w<N>dp h<N>dp sw<N>dp 格式的修饰符,来适配屏幕的宽高,如果有一个w411dp资源,
    当手机的屏幕小于这个尺寸的时候;411设置的是最低数值了,那么手机依然会使用w411dp适配的资源


    w:128dp 适配411dp资源
    w:500dp 适配533 资源
    -------------------------------------------
    100dp                   411dp        533dp


    +++++++++++++++++++++++++++++++++++++++++++++
    关于w<数值>dp  h<数值>dp
    +++++++++++++++++++++++++++++++++++++++++++++
    切换屏幕的时候,要注意了
    1:关于w,h修饰符,随着设备的旋转,高度,宽度会交换,
    这种情况下,将会影响适配情况。
    2:通常如果只关注,最小宽度的情况
    例如,给电视配置:
    使用最短边适配会更好;也就是sw<数值>dp
    sw代表屏幕硬件上面短的边的数值适配,就不会出现宽高交换的问题
    也就是类似于values-sw600dp












    最短边,sw的应用:
    根据实际的dp来进行
    values 里面出现了values-w820dp
    <resources>
        <!-- Example customization of dimensions originally defined in res/values/dimens.xml
             (such as screen margins) for screens with more than 820dp of available width. This
             would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
        <dimen name="activity_horizontal_margin">64dp</dimen>
    </resources>




    ==============================================================
        //通过API获取屏幕宽度,高度,dp数值
            WindowManager windowManager = getWindowManager();
            //获取的显示屏
            Display defaultDisplay = windowManager.getDefaultDisplay();
            //获取屏幕的测量信息,包括屏幕的宽高信息;
            DisplayMetrics outMetrics = new DisplayMetrics();
            //还能获取手机的dpi到底是多少,
            defaultDisplay.getMetrics(outMetrics);
            //手机DPI
            int densityDpi = outMetrics.densityDpi;
            //宽高的实际像素
            int widthPixels = outMetrics.widthPixels;
            int heightPixels = outMetrics.heightPixels;


            //px=(dpi/150)*dp
            //scaledDensity=(dpi/150)
            float scaledDensity = outMetrics.scaledDensity;


            //宽度dp,高度dp
            float wDp = widthPixels / scaledDensity;
            float hDp = heightPixels / scaledDensity;


            Log.d("151226MY","densityDpi="+densityDpi);
            Log.d("151226MY","width="+widthPixels);
            Log.d("151226MY","height="+heightPixels);
            Log.d("151226MY","scaleDensity="+scaledDensity);
            Log.d("151226MY","wdp="+wDp);
            Log.d("151226MY","hDp="+hDp);
        }


    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: densityDpi=320
    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: width=720
    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: height=1280
    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: scaleDensity=2.0
    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: wdp=360.0
    12-26 16:53:02.297 10471-10471/com.kodulf.adapte D/151226MY: hDp=640.0


    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: densityDpi=240
    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: width=480
    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: height=800
    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: scaleDensity=1.5
    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: wdp=320.0
    12-26 16:58:38.712 21315-21315/com.kodulf.adapte D/151226MY: hDp=533.3333


    d->density 密度


    右键res 
    目录
    ScreenWidth
    输入360
    会得到values-w360dp的文件夹


    新建strings


    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="width_info">360</string>
    </resources>




    新建dimens.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <dimen name="new_image_size">120dp</dimen>
    </resources>


    +++++++++++++++++++++++++++++++++++++++++++
    开发过程中是否用权重更多呢?
    ?????????????????????????
    ++++++++++++++++++++++++++++++++++++++++++++++
    Android 版本的适配:
    1:使用Android support 包,实现高版本API的兼容;
    ActionBar就是v7包的,Fragment 是v4包
    2:通常由于采用一些新的API兼容包,那么软件最低支持Android 2.1就是API7
    3:确认软件最低支持版本的时候,需要分析使用API最低支持到那个版本;


    例如如果设置最低的版本是9
    现在设置一个
    Button btn=null;
    btn.setX(34);


    Develpe-》Reference-》API level




    版本适配:
    1:确定最低版本,不要调用最低版本以上的任何代码
    2:如果调用的高版本方法,有对应的低版本的代替
    例如View.setX()高版本,可以使用View.setLeft+View.setRight()这种低版本方法,代替
    那么就可以通过代码来进行倒台的适配;
    android.os.Build 这个类,就可以获取当前手机的各种信息,包括version
    Button btn=null;
    if(Build.VERSION.SDK_INT>=11){
    btn.setX(34);
    }else{
    Toast.....("您的手机不支持。。。")
    }




    =========================================================================
    硬件适配:
    1:只有在清单文件会有这个要求,应用市场里里面,我们的清单文件会有作用的
    应用市场软件需要使用那些硬件,在清单文件声明;是否是必须的;


    2:应用市场会根据手机的特性,显示对应的软件,根据清单文件,过滤不支持的程序。
    Trainning->Supporting Different Devices


    <uses-feature android:name="android.hardware.camera" android:required="true"/>






    Android 开发的
    http://developer.android.com/guide/practices/screens_support.html
    http://developer.android.com/design/style/devices-displays.html


    屏幕适配,
    先要了解什么是dp,dpi,sp
    dpi是dot per inch,每英寸多少个点。一英寸是多少呢?1英寸(in)=2.54厘米(cm),最简单就是一寸照片的底部就是一寸长的。
      正常的USB的接口长度是13.4,也就是说usb接口长度大概略大于0.5英寸。
      红米手机2的机身尺寸为134×67.2×9.4mm,长度为下部的宽度也就是2.6英寸,分辨率为720x1280,按照这个说,dpi应该是300左右。 
     红米手机的px 大概= dp*(320/160)=2dp.
    而三星手机,480*640的分辨率,下面大概是2.4英寸长度,那么也就是说dpi应该是200左右。
    三星手机的px 大概是dp*(200/160)=1.25dp.


    px = dp * (dpi / 160)


    The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen






    Density-independent pixel (dp)
    A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
    The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.


    A set of six generalized densities:
    ldpi (low) ~120dpi
    mdpi (medium) ~160dpi
    hdpi (high) ~240dpi
    xhdpi (extra-high) ~320dpi
    xxhdpi (extra-extra-high) ~480dpi
    xxxhdpi (extra-extra-extra-high) ~640dpi



    展开全文
  • Android系统发布十多年以来,关于Android的UI的适配一直是开发环节中最重要的问题,但是我看到还是有很多小伙伴对Android适配方案不了解。刚好,近期准备对糗事百科Android客户端设计一套UI尺寸适配方案,可以和小...

    Android系统发布十多年以来,关于Android的UI的适配一直是开发环节中最重要的问题,但是我看到还是有很多小伙伴对Android适配方案不了解。刚好,近期准备对糗事百科Android客户端设计一套UI尺寸适配方案,可以和小伙伴们详细的聊一聊这个问题。

    Android适配最核心的问题有两个,其一,就是适配的效率,即把设计图转化为App界面的过程是否高效,其二如何保证实现UI界面在不同尺寸和分辨率的手机中UI的一致性。这两个问题都很重要,一个是保证我们开发的高效,一个是保证我们适配的成效;今天我们就这两个核心的问题来聊一聊Android的适配方案。

    首先,大家都知道,在标识尺寸的时候,Android并不推荐我们使用px这个真实像素单位,因为不同的手机之间,分辨率是不同的,比如一个96*96像素的控件在分辨率越来越高的手机上会在整体UI中看起来越来越小。

    image

    出现类似于上图这样这样,整体的布局效果可能会变形,所以px这个单位在布局文件中是不推荐的。

    dp直接适配

    针对这种情况,Android推荐使用dp作为尺寸单位来适配UI.

    那么什么是dp?dp指的是设备独立像素,以dp为尺寸单位的控件,在不同分辨率和尺寸的手机上代表了不同的真实像素,比如在分辨率较低的手机中,可能1dp=1px,而在分辨率较高的手机中,可能1dp=2px,这样的话,一个96*96dp的控件,在不同的手机中就能表现出差不多的大小了。那么这个dp是如何计算的呢? 我们都知道一个公式: px = dp(dpi/160) 系统都是通过这个来判断px和dp的数学关系,

    那么这里又出现了一个问题,dpi是什么呢?

    dpi是像素密度,指的是在系统软件上指定的单位尺寸的像素数量,它往往是写在系统出厂配置文件的一个固定值。

    我为什么要强调它是软件系统上的概念?因为大家买手机的时候,往往会听到另一个叫ppi的参数,这个在手机屏幕中指的也是像素密度,但是这个是物理上的概念,它是客观存在的不会改变。dpi是软件参考了物理像素密度后,人为指定的一个值,这样保证了某一个区间内的物理像素密度在软件上都使用同一个值。这样会有利于我们的UI适配。

    比如,几部相同分辨率不同尺寸的手机的ppi可能分别是是430,440,450,那么在Android系统中,可能dpi会全部指定为480.这样的话,dpi/160就会是一个相对固定的数值,这样就能保证相同分辨率下不同尺寸的手机表现一致。

    而在不同分辨率下,dpi将会不同,比如:

    ... 1080*720 1920*1080
    dpi 320 480
    dpi/160 2 3

    根据上面的表格,我们可以发现,720P,和1080P的手机,dpi是不同的,这也就意味着,不同的分辨率中,1dp对应不同数量的px(720P中,1dp=2px,1080P中1dp=3px),这就实现了,当我们使用dp来定义一个控件大小的时候,他在不同的手机里表现出相应大小的像素值。

    image

    我们可以说,通过dp加上自适应布局和weight比例布局可以基本解决不同手机上适配的问题,这基本是最原始的Android适配方案。

    这种方式存在两个小问题,第一,这只能保证我们写出来的界面适配绝大部分手机,部分手机仍然需要单独适配,为什么dp只解决了90%的适配问题,因为并不是所有的1080P的手机dpi都是480,比如Google 的Pixel2(1920*1080)的dpi是420,也就是说,在Pixel2中,1dp=2.625px,这样会导致相同分辨率的手机中,这样,一个100dp*100dp的控件,在一般的1080P手机上,可能都是300px,而Pixel 2 中 ,就只有262.5px,这样控件的实际大小会有所不同。

    为了更形象的展示,假设我们在布局文件中把一个ImageView的宽度设置为360dp,那么在下面两张图中表现是不一样的:

    图一是1080P,480dpi的手机,图二是1080P,420dpi的手机

    1080P,480dpi的手机

     

    1080P,420dpi的手机

    从上面的布局中可以看到,同样是1080P的手机,差异是比较明显的。在这种情况下,我们的UI可能需要做一些微调甚至单独适配。

    第二个问题,这种方式无法快速高效的把设计师的设计稿实现到布局代码中,通过dp直接适配,我们只能让UI基本适配不同的手机,但是在设计图和UI代码之间的鸿沟,dp是无法解决的,因为dp不是真实像素。而且,设计稿的宽高往往和Android的手机真实宽高差别极大,以我们的设计稿为例,设计稿的宽高是375px*750px,而真实手机可能普遍是1080*1920,

    那么在日常开发中我们是怎么跨过这个鸿沟的呢?基本都是通过百分比啊,或者通过估算,或者设定一个规范值等等。总之,当我们拿到设计稿的时候,设计稿的ImageView是128px*128px,当我们在编写layout文件的时候,却不能直接写成128dp*128dp。在把设计稿向UI代码转换的过程中,我们需要耗费相当的精力去转换尺寸,这会极大的降低我们的生产力,拉低开发效率。

    宽高限定符适配

    为了高效的实现UI开发,出现了新的适配方案,我把它称作宽高限定符适配。简单说,就是穷举市面上所有的Android手机的宽高像素值:

    image

    设定一个基准的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。

    比如以480x320为基准分辨率

    • 宽度为320,将任何分辨率的宽度整分为320份,取值为x1-x320
    • 高度为480,将任何分辨率的高度整分为480份,取值为y1-y480

    那么对于800*480的分辨率的dimens文件来说,

    x1=(480/320)*1=1.5px

    x2=(480/320)*2=3px

    ...

    image

    这个时候,如果我们的UI设计界面使用的就是基准分辨率,那么我们就可以按照设计稿上的尺寸填写相对应的dimens引用了,而当APP运行在不同分辨率的手机中时,这些系统会根据这些dimens引用去该分辨率的文件夹下面寻找对应的值。这样基本解决了我们的适配问题,而且极大的提升了我们UI开发的效率,

    但是这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。

    不过这个方案有一些团队用过,我们可以认为它是一个比较成熟有效的方案了。

    UI适配框架(已经停止维护)

    鸿洋大佬的适配方案的项目也来自于宽高限定符方案的启发。

    使用方法也很简单:

    第一步:
    在你的项目的AndroidManifest中注明你的设计稿的尺寸。

    <meta-data android:name="design_width" android:value="768">
    </meta-data>
    <meta-data android:name="design_height" android:value="1280">
    </meta-data>
    

    第二步:
    让你的Activity继承自AutoLayoutActivity.

    然后我们就可以直接在布局文件里面使用具体的像素值了,比如,设计稿上是96*96,那么我们可以直接写96px,APP运行时,框架会帮助我们根据不同手机的具体尺寸按比例伸缩。

    这可以说是一个极好的方案,因为它在宽高限定符适配的基础上更进一步,并且解决了容错机制的问题,可以说完美的达成了开发高效和适配精准的两个要求。

    但是我们能够想到,因为框架要在运行时会在onMeasure里面做变换,我们自定义的控件可能会被影响或限制,可能有些特定的控件,需要单独适配,这里面可能存在的暗坑是不可预见的,还有一个比较重要的问题,那就是整个适配工作是有框架完成的,而不是系统完成的,一旦使用这个框架,未来一旦遇到很难解决的问题,替换起来是非常麻烦的,而且项目一旦停止维护,后续的升级就只能靠你自己了,这种代价团队能否承受?当然,它已经停止维护了。

    不过仅仅就技术方案而言,不可否认,这是一个很好的开源项目。

    小结

    讨论的上述几种适配方案都是可以实际用于开发中的比较成熟的方案,而且确实有很多开发者正在使用。不过由于他们各自都存在一些缺陷,所以我们使用了上述方案后还需要花费额外的精力着手解决这些可能存在的缺陷。

    那么,是否存在一种相对比较完美,没有明显的缺陷的方案呢?

    smallestWidth适配

    smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。

    这种机制和上文提到的宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。

    举个例子,小米5的dpi是480,横向像素是1080px,根据px=dp(dpi/160),横向的dp值是1080/(480/160),也就是360dp,系统就会去寻找是否存在value-sw360dp的文件夹以及对应的资源文件。

    image

    smallestWidth限定符适配和宽高限定符适配最大的区别在于,前者有很好的容错机制,如果没有value-sw360dp文件夹,系统会向下寻找,比如离360dp最近的只有value-sw350dp,那么Android就会选择value-sw350dp文件夹下面的资源文件。这个特性就完美的解决了上文提到的宽高限定符的容错问题。

    这套方案是上述几种方案中最接近完美的方案。
    首先,从开发效率上,它不逊色于上述任意一种方案。根据固定的放缩比例,我们基本可以按照UI设计的尺寸不假思索的填写对应的dimens引用。
    我们还有以375个像素宽度的设计稿为例,在values-sw360dp文件夹下的diemns文件应该怎么编写呢?这个文件夹下,意味着手机的最小宽度的dp值是360,我们把360dp等分成375等份,每一个设计稿中的像素,大概代表smallestWidth值为360dp的手机中的0.96dp,那么接下来的事情就很简单了,假如设计稿上出现了一个10px*10px的ImageView,那么,我们就可以不假思索的在layout文件中写下对应的尺寸。

    image

    而这种diemns引用,在不同的values-sw<N>dp文件夹下的数值是不同的,比如values-sw360dp和values-sw400dp,

    image

    image

    当系统识别到手机的smallestWidth值时,就会自动去寻找和目标数据最近的资源文件的尺寸。

    其次,从稳定性上,它也优于上述方案。原生的dp适配可能会碰到Pixel 2这种有些特别的手机需要单独适配,但是在smallestWidth适配中,通过计算Pixel 2手机的的smallestWidth的值是411,我们只需要生成一个values-sw411dp(或者取整生成values-sw410dp也没问题)就能解决问题。

    smallestWidth的适配机制由系统保证,我们只需要针对这套规则生成对应的资源文件即可,不会出现什么难以解决的问题,也根本不会影响我们的业务逻辑代码,而且只要我们生成的资源文件分布合理,,即使对应的smallestWidth值没有找到完全对应的资源文件,它也能向下兼容,寻找最接近的资源文件。

    当然,smallestWidth适配方案有一个小问题,那就是它是在Android 3.2 以后引入的,Google的本意是用它来适配平板的布局文件(但是实际上显然用于diemns适配的效果更好),不过目前所有的项目应该最低支持版本应该都是4.0了(糗事百科这么老的项目最低都是4.0哦),所以,这问题其实也不重要了。

    还有一个缺陷我忘了提,那就是多个dimens文件可能导致apk变大,这是事实,根据生成的dimens文件的覆盖范围和尺寸范围,apk可能会增大300kb-800kb左右,目前糗百的dimens文件大小是406kb,我认为这是可以接受的。

    今日头条适配方案(更新)

    文章链接,之前确实没有接触过,我简单看了一遍,可以说,这也是相对比较完美的方案,我先简单说一下这个方案的思路,它是通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。

    比如,设计稿宽度是360px,那么开发这边就会把目标dp值设为360dp,在不同的设备中,动态修改density值,从而保证(手机像素宽度)px/density这个值始终是360dp,这样的话,就能保证UI在不同的设备上表现一致了。

    这个方案侵入性很低,而且也没有涉及私有API,应该也是极不错的方案,我暂时也想不到强行修改density是否会有其他影响,既然有今日头条的大厂在用,稳定性应当是有保证的。

    但是根据我的观察,这套方案对老项目是不太友好的,因为修改了系统的density值之后,整个布局的实际尺寸都会发生改变,如果想要在老项目文件中使用,恐怕整个布局文件中的尺寸都可能要重新按照设计稿修改一遍才行。因此,如果你是在维护或者改造老项目,使用这套方案就要三思了。

    福利赠送

    生成diemns文件的过程以及数据计算方法上面已经讲清楚了,大家完全可以自己去生成这些文件,我在这里附赠生成values-sw<N>的项目代码,大家直接拿去用,是Java工程。点击这里获取项目地址

    关于一些问题

    Q: 该适配方案怎么用?

    A:点击进入上文的github项目,下载到本地,然后运行该Java工程,会在本地根目录下生成相应的文件,如果需要生成更多尺寸,在DimenTypes 文件中填写你需要的尺寸即可。

    Q: 是否有推荐的尺寸?

    A 300,320,360,411,450,这几个尺寸是比较必要的,然后在其中插入一些其他的尺寸即可,如果不放心,可以在300-450之间,以10为步长生成十几个文件。

    Q:平板适配的问题?

    A: 这个可以分成两个问题,第一,团队有没有专门针对平板设计UI?第二,才是如何对平板适配。如果团队内部没有针对平板设计UI,那么大家对于App在平板上运行的要求大抵也就是不要太难看即可。针对这种情况的适配方法是被动适配,即不要生成480以上的适配文件,这样在平板上,系统就会使用480这个尺寸的dimens文件,这样效果比主动适配更好;而如果团队主动设计了平板的UI,那么我们就需要主动生成平板的适配文件,大概在600-800之间,关键尺寸是640,768。然后按照UI设计的图来写即可。

    Q:用了这套方案是否就不需要使用wrap_content等来布局了?

    A:这是绝对错误的做法!如果UI设计上明显更适合使用wrap_content,match_parent,layout_weight等,我们就要毫不犹豫的使用,而且在高这个维度上,我们要依照情况设计为可滑动的方式,或者match_parent,尽量不要写死。总之,所有的适配方案都不是用来取代match_parent,wrap_content的,而是用来完善他们的



    作者:拉丁吴
    链接:https://www.jianshu.com/p/a4b8e4c5d9b0
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    展开全文
  •  Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app...

    一、引言

      Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app的兼容性,各种定制的rom不经意间就让app崩溃,光是界面上的调整就已经够你喝一壶了,是不?

    二、适配可行性

      早在Android设计之初就考虑到了这一点,为了让app适应标准or山寨屏幕,google已经有一套成熟的解决方案。其中,有这么几个指标需要注意:

      (1)屏幕尺寸:单位inch,指的是屏幕对角线长度。

      (2)屏幕密度:单位dpi,指的是每inch上可以显示多少像素点即px。

      (3)屏幕分辨率:单位px * px,指的是一屏显示多少像素点。

      (4)屏幕无关像素:单位dp/dip,指的是自适应屏幕密度的像素,用于指定控件宽高。

      (5)刻度无关像素:单位sp,指的是自适应字体的像素,用于指定文字大小。

      以我自己的Haier W910超级战舰(宽高比16:9)为例,上述单位的换算如下:

      已知数据:屏幕尺寸4.5, 分辨率1280 * 720, 屏幕密度320

      (1)16:9的4.5寸屏幕由勾股定理计算其高约为3.9寸,宽约为2.2寸

      (2)则竖向dpi为1280 / 3.9 ≈ 328, 横向dpi为720 / 2.2 ≈ 327

      (3)工业上切割液晶板时取整为320

       那么既然dpi是自适应屏幕密度的,与px之间又是如何换算呢:

      120dpi(ldpi低密度屏)       1dp = 0.75px        (由于像素点是物理点,所以用2个像素点来显示3个dp的内容)

      160dpi(mdpi中密度屏)     1dp = 1px

      213dpi(tvdpi电视密度屏)  1dp = 1.33px

      240dpi(hdpi高密度屏)      1dp = 1.5px

      320dpi(xhdpi极高密度屏)   1dp = 2px

      由上述分析结果可知,控件使用dp,文字使用sp即可满足自适应的需求。

    三、适配方案

      根据目前的调查,在市面上的平板,基本上属于mdpi和hdpi的,少数属于tvdpi(如google出的nexus7),所以我们选择这三种密度考虑适配;此外手机应用大多数都是竖屏使用,但平板作为娱乐性的一款产品,横竖屏均有使用的时候,所以我们还需要考虑到屏幕状态进行适配;最后考虑到有的rom会将虚拟键计算到屏幕尺寸里,还要考虑到虚拟键所占用的长宽。

      那么如何根据这三个属性来进行适配呢?Android在资源文件values用文件名的方式提供了限定符可以帮助我们判断上述情况,限定符(mdpi,tvdpi,hdpi)可以帮助我们判断屏幕密度,限定符(land,port)可以帮助我们区分屏幕横竖屏状态,而限定符(1024x600...)可以适配计算虚拟键或者不计算虚拟键的屏幕,限定符的详细说明请参见Android SDK文档中开发者指南的Supporting Multiple Screens话题。

      最终适配文件夹如下图所示:

      

      注1:分辨率限定符的匹配是向下匹配,如果没有values-land-mdpi-1024x552,比如,分辨率values-land-mdpi-1024x600的屏幕,当rom不把虚拟键计算到屏幕尺寸时,实际显示的屏幕应该是values-land-mdpi-1024x552,无法适配到values-land-mdpi-1024x600,那这样就可能适配到下一级,比如values-land-mdpi-800x480,但是现在的平板已经没有这么低的分辨率了,所以是配到无限定符的values-mdpi里,造成界面显示上的瑕疵。

      注2:由于分辨率限定符的匹配是向下匹配,所以如果有非主流mdpi屏幕不能精确适配到上述指定值时,values-mdpi至少可以保证app运行时不至于崩溃,同理values可以保证ldpi屏幕的平板不会因生成view而又取不到相应值而崩溃。

    文章转自: http://www.cnblogs.com/zealotrouge/archive/2012/11/23/2784774.html
    展开全文
  • 如何将一个应用程序适配在不同的手机上,虽然这不算是一个技术问题,但是对于刚刚做屏幕的开发人员来说,还真不是一件多么简单的事情。 首先:你需要在AndroidManifest.xml文件的元素如下添加子元素 supports-...
      如何将一个应用程序适配在不同的手机上,虽然这不算是一个技术问题,但是对于刚刚做屏幕的开发人员来说,还真不是一件多么简单的事情。

    首先:你需要在
    AndroidManifest.xml文件的<manifest>元素如下添加子元素

    <supports-screens android:largeScreens="true"

          android:normalScreens="true"android:anyDensity="true"

          android:smallScreens="true"></supports-screens>

        名如其意,以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。android:anyDensity="true" 这一句对整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。

    相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,如果设置android:anyDensity="false"Android系统会将240 x 320(低密度)转换为320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。

     

    2.细心的人会发现自android2.0开始之后drawable文件被三个文件夹drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹所取代,有些编程人员为了让应用程序默认地加载某些图片,他们会特意地去在android2.0之后的应用程序中重新创建drawable文件夹,其实这样做完全没有必要,通过第一段的分析我们得知,android:anyDensity="false"则应用会将大小密度转变成中密度,从而去加载mdpi中的资源。这里同样,当android:anyDensity="false"则应用会去加载mdpi中的资源。

    总结一下:

    第一:android:anyDensity="true"系统会依据屏幕密度,自动去找对应的文件夹

    第二:android:anyDensity="false",

    (1)             如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载drawable_mdpi文件夹中的资源

    (2)             如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。

    (3)             如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,那么系统会加载drawable-mdpi文件夹中的资源

     

    3. 注意上图各种文件夹的不同表示。

    drawable-hdpi 该图片即适用于横屏,也适用于竖屏

    drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源

    drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源


    3. 有时候会根据需要在代码中动态地设置某个值,比如地图,地图的pin和地图的地址提示框的相对偏移量在不同密度的手机上是不同的。这时候可以通过以下方法求出屏幕密度:

    DisplayMetrics metric = newDisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metric);

    int densityDpi =metric.densityDpi;  //屏幕密度DPI120 / 160 / 240

    然后可以在代码中为这几种密度分别设置便宜量

    但是这种方法最好不要使用,最好的方式是在xml文件中不同密度的手机进行分别设置。
    这里地图的偏移量可以在values-hpdi,values-mdpi,values-ldpi三种文件夹中的dimens.xml文件进行设置
    值得一提的是:

       <dimen name="bitmap_common_topoffset">40dp</dimen>

       <dimen name="bitmap_common_bottomoffset">-14dp</dimen>
    这里的负数是完全起作用的,系统会认为它是一个负值


    4.各大手机厂商对于Android操作系统都有或多或少的改动,当然这些改动会对我们应用程序产生某些影响
      比如:
      (1)系统源代码中连接music服务的aidl文件所在包名:com.android.music
      (2)LG则可能将该aidl文件修改所在的包(例如修改为com.android.music.player),并且修改其中的文件内容(增加一个方法,或者减少几个方法,或者修改方法名称)那么我们的应用要想在LG的手机上发布,那么我们就必须改变所要连接的aidl文件,必须跟LG厂商修改的完全一致。
    展开全文
  • dpi,分辨率,dp,sp,px这些东西,相信每个android开发者都不陌生,但是这几者之间的关系,能够说得清清楚楚的,我相信并不多。 看完这篇博客,希望能让你彻彻底底的理解它们。一. DPI 首先说dpi,废话是:每英寸...
  •  Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app...
  • Android 屏幕适配方案

    2015-08-01 13:20:53
    1、概述大家在Android开发时,肯定会觉得屏幕适配是个尤其痛苦的事,各种屏幕尺寸适配起来蛋疼无比。如果我们换个角度我们看下这个问题,不知道大家有没有了解过web前端开发,或者说大家对于网页都不陌生吧,其实...
  • Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因、重要概念、解决方案及最佳实践,我相信如果你能认真的学习本文,对于Android的...
  • Android开发中有时会遇到在不同的手机上界面不适配的问题,控件忽大忽小,而且就连两个分辨率相同的手机有时也会出现这种问题。其实出现界面适配问题的原因,并不仅仅有分辨率,还有一个更重要的因素是:屏幕密度...
  • Android开发必备知识--适配问题(全)+资源值加载问题+dpi分辨率问题
  • Android屏幕适配方案

    2018-10-17 18:33:09
    目录介绍 1.屏幕适配定义 2.相关重要的概念 2.1 屏幕尺寸[物理尺寸] ...2.3 屏幕像素密度[dpi] ...3.Android屏幕适配出现的原因 3.1 什么是像素点 3.2 dp与百分比 4.Android适配问题及本质 4.1 尺寸...
  • A low-cost Android screen adaptation solution (今日头条屏幕适配方案终极版,一个极低成本的 Android 屏幕适配方案). Overview Pixel 2 XL | 1440 x 2880 | 560dpi: Pixel XL | 1440 x 2560 | 560dpi: ...
  • Android发展至今,功能越来越多,越来越强大,不过碎片化的问题也是众所周知的越来越严重,如果是做大众应用,我相信屏幕适配肯定是我们不可回避的一个问题,当然了,网上的适配方案有很多,比如: Google的百度...
  • 1. 图片最终的显示还是像素,在像素的基础上google整理出来一套规范,dip(dp)和...2. Density对应的是密度,是一个比例值,计算公式:density = dpi / 160 像素/英寸,160像素/英寸是android定义的一个标准(计算规
  • 如何确定设备的res dpi 目标设备res-dpi信息获取方法: /** * 一般情况下的普通屏幕:ldpi是120,mdpi是160,hdpi是240,xhdpi是320。 * 屏幕信息详情{@link android.util.DisplayMetrics} */ private ...
  • gen_dpi 根据屏幕密度生成适配的px尺寸
  • Android 的屏幕适配是指适配不同机顶盒 UI 框架层输出的分辨率和 dpi,而不是适配不同分辨率的电视机(电视机的适配交由机顶盒本身完成,和各个应用无关)。 获取机顶盒 UI 框架层输出的分辨率和 dpi 可以通过以下...
  • 为什么80%的码农都做不了架构师?>>> ...
  •  Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app...
1 2 3 4 5 ... 20
收藏数 6,990
精华内容 2,796
关键字:

dpi适配android