浅谈Android屏幕适配

来源:互联网 发布:linux 拷贝文件夹 空格 编辑:程序博客网 时间:2024/05/19 00:54

我们先来了解下Android屏幕适配的背景

由于Android系统的开放性,任何用户、开发者、OEM厂商、运营商都可以对Android进行定制,修改成他们想要的样子

这无形之中导致了Android屏幕碎片化愈来愈严重,屏幕愈来愈多样化

每一个矩形都代表着一种屏幕尺寸

如需详细数据,请走这边,我的翻译能力还是有限度的,只能保证看懂,但是翻译起来还是有难度的,所以各位看官还是自给自足吧

背景基本就是这样子了,说下基本概念吧

屏幕尺寸

屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米

比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等

屏幕分辨率

屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。

屏幕像素密度

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

dp、dip、dpi、sp、px

px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等。

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

假如同样都是画一条320px的线,在480*800分辨率手机上显示为2/3屏幕宽度,在320*480的手机上则占满了全屏,如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。这也是为什么在Android开发中,写布局的时候要尽量使用dp而不是px的原因。

而sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。

mdpi、hdpi、xdpi、xxdpi

名称 像素密度 启动图标 倍数 mdpi 120dpi-160dpi 48x48px 1x hdpi 160dpi-240dpi 72x72px 1.5x xhdpi 240dpi-320dpi 96x96px 2x xxhdpi 320dpi-480dpi 144x144px 3x xxxhdpi 480dpi-640dpi 192x192px 4x

到这里我们已经基本了解了Android适配的原因和Android适配的名词,接下来便来简单聊聊怎么做Android的屏幕适配工作

1.在适合的情况下使用使用适合的图片,就如下图所示,没有趁手的图片,就用原生图标,你们就凑合着看吧

mdpihdpixhdpixxhdpi

2.合理使用warp_parent,match_parent,weight,权重的使用还是比较多的,也就是大家经常所说的百分比,一般都会使用0dp,较少的使用match_parent。

3.使用相对布局,线性布局,帧布局(FrameLayout),基本不使用绝对布局

相对布局会极大可能做出正确的位置关系,防止两个view之间产生错位的现象

无论使用哪种布局,view的大小都会随着设备dpi的变化产生相应的变化,但是相对位置不会产生过分的变化

标题

这里写图片描述

4.使用尺寸限定符

上面所提到的灵活布局或者是相对布局,可以为我们带来的优势就只有这么多了。虽然这些布局可以拉伸组件内外的空间以适应各种屏幕,但它们不一定能为每种屏幕都提供最佳的用户体验。因此,我们的应用不仅仅只实施灵活布局,还应该应针对各种屏幕配置提供一些备用布局。

如何做到这一点呢?我们可以通过使用配置限定符,在运行时根据当前的设备配置自动选择合适的资源了,例如根据各种屏幕尺寸选择不同的布局。

很多应用会在较大的屏幕上实施“双面板”模式,即在一个面板上显示项目列表,而在另一面板上显示对应内容。平板电脑和电视的屏幕已经大到可以同时容纳这两个面板了,但手机屏幕就需要分别显示。因此,我们可以使用以下文件以便实施这些布局:

res/layout/main.xml,单面板(默认)布局:<?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:orientation="vertical" >    <fragment        android:id="@+id/fragment"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:name="com.example.demo.fragment1" /></LinearLayout>res/layout-sw600dp/main.xml,双面板布局:<?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:orientation="vertical" >    <fragment        android:id="@+id/fragment"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:name="com.example.demo.fragment1" />    <fragment        android:id="@+id/fragment"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:name="com.example.demo.fragment2" /></LinearLayout>

使用布局别名

当存在横竖屏切换的时候,res/layout/layout_land;res/layout/layout_port

只需要对其中大部分xml文件作出相应修改即可满足于横竖屏的切换布局

5.使用.9png

.9的制作,实际上就是在原图片上添加1px的边界,然后按照我们的需求,把对应的位置设置成黑色线,系统就会根据我们的实际需求进行拉伸。

左上边代表拉伸

右下边代表padding box

这里写图片描述

先看下面两张图,我们理解一下这四条线的含义。

这里写图片描述

上图和下图的区别,就在于右下边的黑线不一样,具体的效果的区别,看右边的效果图。上图效果图中深蓝色的区域,代表内容区域,我们可以看到是在正中央的,这是因为我们在右下边的是两个点,这两个点距离上下左右四个方向的距离就是padding的距离,所以深蓝色内容区域在图片正中央,我们再看下图,由于右下边的黑线是图片长度,所以就没有padding,从效果图上的表现就是深蓝色区域和图片一样大,因此,我们可以利用右下边来控制内容与背景图边缘的padding。

这里写图片描述

说白了就是第一张图有padding,这玩意一画全明白

6.距离用dp,文字用sp,不要用px,但是这个dp并不是绝对的,无需考虑太多,因为我们大部分都是使用match和warp的,在相对距离的情况下再使用dp来进行控制**

7.关于高清设计图尺寸的问题

Google官方给出的高清设计图尺寸有两种方案

第一种是 mdpi放大得到hdpi,xhdpi,xxhdpi,xxxhdpi

第二种是xxxhdpi缩小得到xxhdpi,xhdpi,hdpi,mdpi

这两种方法的区别就是:第一种方法容易出席那像素丢失的问题,推荐使用第二种

8.Image的属性:scaleType

一般这个属性都设置为ScaleType="centerCrop"能获得最好的适配效果

9.动态设置

在一些情况下,需要动态设置空间大小或者位置,比如popwindow的显示位置和相对偏移量

我们可以动态获取当前屏幕属性设置合适数值

public class ScreenSizeUtil {    public static int getScreenWidth(Activity activity) {        return activity.getWindowManager().getDefaultDisplay().getWidth();    }    public static int getScreenHeight(Activity activity) {        return activity.getWindowManager().getDefaultDisplay().getHeight();    }}
0 0
原创粉丝点击