android开发学习笔记系列(4)

前言

在做一个有关苏果APP的项目中,但是fuck的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道,只有真正地下手去做某些事情的时候,才会发觉各种问题,原本打算先写view与framgent实现tabhost功能的博客的,但是碰到了这个棘手问题必须先把他解决了!同时不知道各位网友有什么好的方法来适配所有的安卓手机屏幕

问题解决之道

其实解决之道有很多,我选用的是使用代码计算等比例高宽,让其在相应的屏幕上显示相应的比例高度就可以了!当然网上有很多都是给的建议,却没有实实在在解决问题的博客!(希望集思广益,能够得到一个适合全部屏幕类型的架包,方便所有的安卓开发人员)

关于网上的建议

网上的建议,我进行了归纳:

一、关于布局适配二、术语和概念

一般情况下的普通屏幕:ldpi是120,mdpi是160,hdpi是240,xhdpi是320。

三、如何做到自适应屏幕大小呢?1、界面布局方面

需要根据物理尺寸的大小准备5套布局,layout(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的title bar),layout-small(屏幕尺寸小于3英寸左右的布局),layout-normal(屏幕尺寸小于4.5英寸左右),layout-large(4英寸-7英寸之间),layout-xlarge(7-10英寸之间)

2、图片资源方面

需要根据dpi值准备5套图片资源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi

Android有个自动匹配机制去选择对应的布局和图片资源

四、两种获取屏幕分辨率信息的方法:DisplayMetrics metrics = new DisplayMetrics();Display display = activity.getWindowManager().getDefaultDisplay();display.getMetrics(metrics);//这里得到的像素值是设备独立像素dp//DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 这样获得的参数信息不正确,不要使用这种方式。

不能使用android.content.res.Resources.getSystem().getDisplayMetrics()。这个得到的宽和高是空的。

五、关于图片制作关于设计

设计图先定下一个要设计的尺寸,而且尽量采用在目前最流行的屏幕尺寸(比如目前占屏幕比重比较多的是480系列,也即是480×800或者400×854,下面的图标制作也在次基础上进行比例的换算)上设计。 先了解一下屏幕的级别:

说明:

屏幕级别: 注意屏幕级别是按照密度分级,和像素没有关系。如果非要让密度和像素扯上关系,则需要一个参照系,android使用mdpi级别作为标准参照屏幕,也就是说在320×480分辨率的手机上一个密度可以容纳一个像素。然后其他密度级别则在此基础上进行对比。如果理想情况下,480×800的屏幕一个密度可以容纳1.5个像素。

物理大小: 单位是英寸而不是像素,也就说一个英寸在任何分辨率下显示的大小都是一样的,但是像素在密度不同的手机里面显示的实际的大小是不一样的(这就是为什么android手机需要适配的原因)。 然后就是重点。

假设1像素在160密度下显示1英寸,,则1像素在240密度基础上显示大约0.67英寸,在320密度下显示0.5英寸。于是就出现一种情况,在电脑上的一个像素,在不同的手机上看实际的大小不一样。那么怎么让“设计效果”在不同的手机上看起来显示的区域一样呢? 还是假设一个像素在160密度下的显示在一个密度内,也假设就是一英寸。那么需要几个像素才能在240密度级别下显示在一英寸范围内呢?答案是1.5个像素(根据上图的比率换算)。

了解了这个关系,接下来就是图标的制作。

关于切图

关于切图有几个建议: 1.长宽最好是3的倍数(根据android的推荐logo图标的大小是48(mdpi),72(hdpi),96(xhdpi)得出的最小公约数)。 2.长宽最好是偶数。因为奇数在进行等比压缩的时候可能有问题。 3.根据上面两条,如果长宽是6的倍数最理想。 4.如果可以拉伸而不改变设计意图的情况下,比如纯色背景,则使用android的9path工具制作成.9的图片。

关于图标的适配。

然后接下来的一切就和设计稿没什么关系。在切好图的基础上,根据屏幕密度、像素和实际大小的比例关系。假如设计司在480×800的分辨率下做好了设计图,并且切好图,如果你需要适配720×1280屏幕,该怎么做?根据比例,他们的关系是2:3,于是你需要按照1.5倍比例制作图标,比如你在480×800的设计稿上切下来一个20*20像素的图,那么你就需要制作一个等比放大成30×30像素的图标,这样同一个图标在480×800的屏幕和720×1280的屏幕上显示的实际大小才一样。同理,如果你需要适配xxhdpi则需要在20×20的基础上制作一个等比放大成40×40像素的图标。

关于图标的目录

480*800切下来的图我们放在drawable-hdpi目录下,按照2:3放大的图标放在drawable-xhdpi目录下,按照2倍放大的图标放在drawable-xxhdpi目录下。

android会根据手机的密度优先查找对应的目录的资源, 比如408*800分辨率下的手机如果密度是160,则自动加载drawable-hdpi这个目录下的图标, 如果720*1280密度是240的手机自动加载drawable-xhdpi这个目录下的图标。如果没有这个文件夹,则查找和240最接近的对应密度文件夹。

有关个人的解决方法

我个人得到的启示就是我在设计过程中尽量使控件不是使用数值,也就是说我在xml文件所使用的基本都是layout_weight\android:gravity=”center”等,如果迫不得得以使用的话,就先写着,然后通过相应的代码来适配动态布局

代码实现动态布局

目前我所使用的方法呢就是自己写个类,将view传进去进行适配,同时注意了我的方案是可以更改你原来所假设的屏幕宽度,然后一次性地进行适配!

package com.samuel.demosuguo;import android.content.Context;import android.util.DisplayMetrics;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.RelativeLayout;/** * Created by samuelwnb on 2015/3/14. */public class Autosize {int screenwidth = 640;//默认屏幕宽度为640/*** * 得到默认屏幕宽度 * @return */public int getScreenwidth() {return screenwidth;}/*** * 更改默认屏幕宽度 * @param screenwidth */public void setScreenwidth(int screenwidth) {this.screenwidth = screenwidth;}//实际屏幕大小static int screensize = 0;public static void setScreensize(int screensize) {Autosize.screensize = screensize;}/** * 获取屏幕的大小 * @param context//为activity * @return 实际屏幕的打下 */public int Metricwidth(Context context){DisplayMetrics metric = new DisplayMetrics();metric = context.getResources().getDisplayMetrics();return metric.widthPixels;}//获取直接获取屏幕的实际宽度public void GetrealScreenwidth(Context context){DisplayMetrics metric = new DisplayMetrics();metric = context.getResources().getDisplayMetrics();setScreensize(metric.widthPixels);}//设置线性布局下的线性高度public void llinearlayoutheight(int px, LinearLayout linearLayout) {LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();if(screensize != 0) {layoutParams.height = px * screensize / screenwidth;linearLayout.setLayoutParams(layoutParams);}}/***********************控件设置 *///自动设置设置字体的大小public int autosettextsize(int sp){if(screensize != 0) {return sp * screensize / screenwidth;}else {return sp;}}/** * 相对布局中的不同设置高度 *///设置相对布局下的相对布局高度public void relativeLayoutheight(int px, RelativeLayout relativeLayout) {RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();if(screensize != 0) {layoutParams.height = px * screensize / screenwidth;relativeLayout.setLayoutParams(layoutParams);}}//设置相对布局中的相对高度带Margintop设置public void relativeLayoutheightwithmargintop(int px,int margintop, RelativeLayout relativeLayout){RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();if(screensize != 0) {layoutParams.height = px * screensize / screenwidth;layoutParams.topMargin = margintop * screensize / screenwidth;relativeLayout.setLayoutParams(layoutParams);}}public void relativeLayoutheightmargintop(int margintop, RelativeLayout relativeLayout){RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();if(screensize != 0) {layoutParams.topMargin = margintop * screensize / screenwidth;relativeLayout.setLayoutParams(layoutParams);}}//设置相对布局下的线性布局高度public void rlinearlayoutheight(int px, LinearLayout linearLayout) {RelativeLayout.LayoutParams relativelayout = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams();if(screensize != 0) {relativelayout.height = px * screensize / screenwidth;linearLayout.setLayoutParams(relativelayout);}}public void rlinearlayoutheightwithmargintop(int px,int margintop,LinearLayout linearLayout) {RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams();if(screensize != 0) {layoutParams.height = px * screensize / screenwidth;layoutParams.topMargin = margintop * screensize / screenwidth;linearLayout.setLayoutParams(layoutParams);}}public void rlinearlayoutheightmargintop(int margintop,LinearLayout linearLayout) {RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams();if(screensize != 0) {layoutParams.topMargin = margintop * screensize / screenwidth;linearLayout.setLayoutParams(layoutParams);}}

}

而只有在充满了艰辛的人生旅途中,始终调整好自己观风景的心态,

android开发学习笔记系列(4)

相关文章:

你感兴趣的文章:

标签云: