zoukankan      html  css  js  c++  java
  • android 屏幕适配

    android的屏幕适配一直是开发人员头疼的问题。由于android的设备大小不一,并且屏幕显示效果也不同样,怎样对android进行屏幕适配是一个非常大的挑战,为了应对不同的情况。须要细致研究android对不同屏幕的定义。看过学渣的这篇博客。希望大家对屏幕适配有一个主要的了解。

    1 android的屏幕大小

    android的屏幕有大有小,为了对不同大小屏幕的设备提供最好的体验。须要对不同大小的设备进行不同的设计,首先遇到的问题就是android对屏幕大小的区分。

    android的屏幕问题在官网有具体说明,,作为一名学渣,须要细细研读。首先android把屏幕分为四种大小:small,normal,large,xlarge,这四种屏幕首先是直观的区分,即对设备的对角线用尺子量一下,用英寸做单位进行区分。比方学渣用的红米就是4.7英寸。属于normal,具体分类如图1所看到的:


    图1 android屏幕大小区分

    如果你的程序获知android设备屏幕后,依据大小不同能够採用不同的布局方案,可是我们敲代码时,进行布局时,不可能用英寸进行布局,先如果我们使用像素(px)进行布局。可是这里会遇到一个问题,这里须要介绍新的term,请看2。

    。。。

    2 屏幕的分辨率和密度

     这里遇到的问题须要看几个术语,android官网上去后有几个术语介绍,学渣先为大家介绍分辨率和密度

            分辨率(Resolution):The total number of physical pixels on a screen. 即一个设备的物理像素,如1280*720,大家能够自己计算。

        密度(Screen density):The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch).一般我们的密度的单位是像素数目/平方英寸,可是这里推荐了一个新的密度表示方法,就是每英寸的像素数目(dpi)。我们以后用到的密度就是这个dpi

         android里用分辨率和密度这两个域来记录设备的真实尺寸,採用密度的主要原因(学渣猜的)应该是“去英寸化”。即在程序中不要出现英寸这个单位。因此用密度和分辨率这两个值能够保存设备的真实尺寸。

        对于一个程序而言,它能够获取到屏幕的分辨率和尺寸,进而密度=分辨率/尺寸,能够算出尺寸,在android里,获取密度尺寸能够參考这里我们这里用一个小程序来求两个设备的分辨率和密度。学渣定义了两台avd。尺寸都是4.7英寸,设备1的分辨率为800*1280,设备2的分辨率为480*800,測试代码例如以下:

    package com.example.testscreen;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.util.DisplayMetrics;
    import android.view.Menu;
    
    public class MainActivity extends Activity {
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		 DisplayMetrics metrics = new DisplayMetrics();
    		 getWindowManager().getDefaultDisplay().getMetrics(metrics);
    		 
    		 //得到设备的分辨率,即宽和高的像素数目
    		 int height = metrics.heightPixels;
    		 int width = metrics.widthPixels;
    		 
    		 System.out.println("the height is "+height +" the width is" + width);
    		 
    		 //得到设备的密度
    		 int density = metrics.densityDpi;
    		 System.out.println("the density is " + density);
    		
    	}
    }
    

    设备1的输出是:

    06-09 00:10:17.188: I/System.out(2041): the height is 1184 the width is768
    06-09 00:10:17.188: I/System.out(2041): the density is 320

    设备2的输出是:

    06-09 00:45:35.085: I/System.out(2088): the height is 736 the width is480
    06-09 00:45:35.085: I/System.out(2088): the density is 213

        从两个设备的输出能够知道。事实上学渣是定义了两个4.7英寸的avd。可是有着不同的分辨率,(android里有底部栏。看起来有点不一样),这两个样例说明了一个问题:同样大小的手机,能够有不同的分辨率,进而就有不同的密度喽,(由于密度=分辨率/大小)。

    3 程序推断屏幕大小

          每一个程序都须要判定屏幕的大小,进而选择合适的布局(后面会说)。怎样判定大小(设备的真实尺寸,能够理解为设备对角线的英寸数)呢,就依据2所提到的两个參数来推断,一个是分辨率。一个是密度,用设备1而言,知道height是1184像素(px)。其密度为320dpi(像素/英寸),则高度的详细值就是1280/320=4(英寸)。宽度为800/320=2.5 ,用勾股定理算出对角线的长度,(学渣这里没有细算)再和图1匹配,得到这个设备的屏幕大小尺寸。

          屏幕大小判定之后,首先须要在mainfest声明支持的屏幕大小,如:

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

                 要想要好的用户体验,程序能够依据不同的大小选择不同的布局,android官方文档里也提到了,能够对不同的大小。设置不同的layout,如res/layout-large就是large屏幕时所採用的布局。

        官方文档里有这么几句话要注意:Beginning with Android 3.2 (API level 13), the above size groups are deprecated and you should instead use the sw<N>dp configuration qualifier to define the smallest available width required by your layout resources. For example, if your multi-pane tablet layout requires at least 600dp of screen width, you should place it inlayout-sw600dp/.即对于3.2以上的,直接採用dp(dp相当于一种程序中的英寸大小)进行推断屏幕的宽度。进而选择不同的布局,如/res/layout-sw600dp,就是宽度要求是600dp以上的我们就选择这个布局。

    只是意思和small,large等一样,仅仅只是把大小换成了详细的数字。

    3 去英寸化 

       上面我们提到了去英寸化。怎样让一个程序能够非常好的显示大小呢。似乎能够採用像素?可是这是全然不能够的。先举一个简单的样例说明像素的缺陷,还是採用上述的设备1和设备2进行測试,我们在设备1和设备2都定义一个button,宽度和高度都为200px(像素),效果如图2所看到的:


    图2 同样大小的手机,同样的像素大小的button

          事实上这个结果一点也不意外,这是由于两个button的像素大小尽管一样,可是密度不同。而最后的真实大小是依照英寸来画的,由于密度=像素/英寸,则 真实大小(英寸数)=像素/密度

    那么这个问题怎么破,由于我们的程序一定是在同样大小的屏幕上有同样的大小,假设两个空间的大小一样,则是其英寸数相等。而英寸数又不能直接写在程序里。于是乎出现一个逆天的术语,dp。事实上在2里我们看到过这个dp,那么什么是dp呢?

           dp在官网里叫Density-independent pixel (dp),即密度无关的像素。即能够摆脱密度的缠绕。就是前面我所提到的一种具有“去英寸化”功能的新的单位。我们先不提dp的详细计算(后面会说),我们就先如果这个dp就是一个全新的度量单位,让相等的dp在不同密度的屏幕里有相等的长度,比方1dp不管你是在设备1还是设备2,大小都是相等。

    这就是攻克了“去英寸化”的问题。

    4 dp的应用与图片问题

       通过3的描写叙述,我们应该能够知道,在layout里不论什么的控件都採用dp就能够保证显示一致的问题了。

    这也是google所推荐的。

        可是对于图片这样的外来户。我们能够规定它在layout中的大小,假如我们规定了图片的宽度1英寸(能够转为dp,后面会将)。对于一张图片。其真实的宽度为15像素。在密度为3dpi的屏幕中。能够显示3个像素,这时须要丢掉12个像素,图片一定极为不清晰;在密度为15dpi的屏幕里能够显示15个像素。显示全然。这就有了分辨率的问题,在宽度都为1英寸的情况下,肯定是能够显示所有15个像素的图片清晰,怎么能让不同密度的屏幕显示的照片都比較清晰呢,我们能够对不同密度的屏幕选择不同的图片,即高密度选择高清图片

    对于不论什么一张图片。我们都能够做三张,一张低分辨率,一张高分辨率。一张中间值,对于高密度的屏幕,比方密度为15。我们选择一张分辨率较高的图片(就是大的图片)。如15英寸的,对于密度为3的。我们让它显示一张分辨率为3的,则保证了不会丢失信息,从而保证图片清晰。

        对于不同密度的屏幕,能够通过/res/drawable-hdpi等进行选择图片。

    这个官网也有。

    5 dp的计算  

        事实上我们不是必需对dp进行计算,可是为了便于理解,我还是把dp的计算说一下, px = dp * (dpi / 160).这是官网的计算公式。对于一个密度为160dpi的屏幕而言,一个px就等于一个dp。

       另外:android里字体的大小採用sp,详细的还没有研究,只是作用预计和dp几乎相同。

    这篇博客花了学渣一个中午的时间,对于android的学习,学渣觉得应该以官网为主要參考。假设本文内容有误。欢迎指出,谢谢!

  • 相关阅读:
    ANT安装
    MAVEN配置教程
    闲笔
    js系列
    微信小程序系列_require
    c++复习系列
    codeblocks系列
    mysql系列
    Google Developer Tools
    数学建模算法(三):神经网络
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7026533.html
Copyright © 2011-2022 走看看