1. 什么是density
引用
1) density
density表示每英寸有多少个显示点(逻辑值),它的单位是dpi:dot per inch,通常屏幕大时,density就大,屏幕小时,density就小,通常
屏幕实际分辨率为240px*400px时,density=120
屏幕实际分辨率为320px*533px,density=160
屏幕实际分辨率为480px*800px,density=240
2) 分辨率
是整个屏是多少点,比如800x480,它是软件的显示单位
3) 从Android1.6版本开始支持density(对应API Level 4)
用于解决应用在屏幕大小不同的硬件上正常显示的问题
2. 相关代码及设置
引用
1) AndroidManifest.xml
<SUPPORTS-SCREENS android:anyDensity="true" />
<USES-SDK android:minSdkVersion="4">
这个参数在API Level 4也就是SDK 1.6以后才启用的,而且1.6版本的API Level 4的应用默认值就是True
2) 资源目录名(android 2.0以后)
res/xxx-hdpi 当density为240时,使用此目录下的资源
res/xxx-mdpi 当density为160时,使用此目录下的资源
res/xxx-ldpi 当density为120时,使用此目录下的资源
res/xxx 不常后缀,为默认设置,同xxx-mdpi
3) 资源单位(xml文件中定义大小的单位)
a) dp=dip=dx (Density independent pixel)
基于屏幕密度的抽象单位,设备无关的点,用于说明与密度无关的尺寸和位置。这些单位是相对于一个160dpi的屏幕,所有一个dp是160dpi屏幕上的一个点。
b) px
px指软件的单位点,设备相关的点
c) 具体使用
i.布局时尽量使用单位dip,少使用px
若使用px,如果设某控件大小400x400px,在800x480上显示正常,而在533x320的屏上就超出屏幕了
若使用dp,如果设某控件大小为160x160dp,就可以通过从系统中取density来算出真正的大小,比如在800x480屏的density设为240,而533x320屏的density设为160,借以下公式计算
pixels = dips * (density / 160)
在800x480在屏中显示240象素,而在533x320的屏中显示为160象素,控件在屏中显示的比例是一样的。
ii. 内部的处理过程分为三步:
取screen中其它元素,转为应用的值,计算应用各控件位置,然后再转成800x480以供真正显示
若res-xxx不存在,则读取res有的资源,然后对其做相应缩放
3. 实现density的关键源码
引用
1) BitmapFactory.java(用于缩放图片)
2) ComptibilityInfo.java(用于位置计算)
4、取得屏幕信息(宽高等)
public static String getDisplayMetrics(Context cx) {
String str = "";
DisplayMetrics dm = new DisplayMetrics();
dm = cx.getApplicationContext().getResources().getDisplayMetrics();
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
float density = dm.density;
float xdpi = dm.xdpi;
float ydpi = dm.ydpi;
str += "The absolute width:" + String.valueOf(screenWidth) + "pixels\n";
str += "The absolute heightin:" + String.valueOf(screenHeight)
+ "pixels\n";
str += "The logical density of the display.:" + String.valueOf(density)
+ "\n";
str += "X dimension :" + String.valueOf(xdpi) + "pixels per inch\n";
str += "Y dimension :" + String.valueOf(ydpi) + "pixels per inch\n";
return str;
}
5 取得状态栏和标题栏高度
TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_test2);
tv1 = (TextView) findViewById(R.id.TextView01);
tv1.post(new Runnable(){
public void run()
{
processLayout();
}
});
}
private void processLayout(){
Rect rect= new Rect();
Window window= getWindow();
tv1.getWindowVisibleDisplayFrame(rect);
//状态栏高度
int statusBarHeight= rect.top;
int contentViewTop= window.findViewById(windows.iD_ANDROID_CONTENT).getTop();
//标题栏高度
int titleBarHeight= contentViewTop - statusBarHeight;
//测试结果:ok之后 100多 ms 才运行了
Log.v("test", "=-init-= statusBarHeight="+statusBarHeight+
" contentViewTop="+contentViewTop+
" titleBarHeight="+titleBarHeight);
}
1. 五不要和九要
1. 不要照搬其他平台上的UI设计。应该让用户感觉是在使用一个真正的 Android 软件,在你的品牌显示和平台整体观感之间做好平衡。
2. 不要过度使用模态进度条和确认对话框。
3. 不要使用固定的绝对定位布局。
4. 不要使用px单位,使用dp;如果是文本,使用sp。
5. 不要使用太小的字体。
1. 所有资源都要针对高分辨率屏幕创建(缩小总比放大好)
2. 需要点击的元素要够大
3. 图标设计要遵循 Android 的准则
4. 要使用适当的间距(margins, padding)
5. 要支持D-pad和trackball导航
6. 要正确管理活动(activity)栈
7. 要正确处理屏幕方向变化
8. 要使用主题/样式、尺寸和颜色资源来减少界面冗余
9. 要和视觉与交互设计师合作!!!
2. 设计理念和考虑因素
设计理念
1. 干净而不过于简单
2. 关注内容而非修饰
3. 一致,吸引人,少量简洁的变化
4. 使用云端服务(同时在PC桌面和手机上同步用户使用场景)来加强用户体验
优秀界面的设计准则
1. 关注用户
了解你的用户(年龄,技能,文化,是否有身体障碍,对应用的需求,使用的设备,何时何地如何使用设备)
“用户优先”的设计心态(用户通常是任务导向的)
更早、更频繁的由真实用户来测试
2. 显示正确的内容
最常用的操作用户应该立即可以看到并且使用
次要功能可以放到菜单里面
3. 给予用户适当的回馈
交互式的UI元素最少需要反映出4种不同的状态 (default,disabled,focused,pressed)
保证操作的结果是清晰可见的
多给予用户进度提示,但是不要干扰他们当前的操作
4. 有章可循的行为模式
行为模式遵循用户的期望(正确的操作活动栈,显示用户期望看到的信息和动作)
使用合适的方式来加强功能可见性(可点击的元素就应该看起来是可以点击的)
如果用户完成一项任务需要复杂的操作,重新思考你的设计!!!
5. 容忍错误
只允许有意义的操作(适当禁用一些UI元素)
尽量减少不可回退的操作
允许回退(undo)比使用确定对话框更好(实际上,应该尽量少用确定对话框,它对用户是一种干扰
设计上的考虑因素
1. 屏幕的物理尺寸
2. 屏幕密度
3. 屏幕的方向(竖向和横向)
4. 主要的UI交互方式(触屏还是使用D-pad/trackball)
5. 软键盘还是物理键盘
6. 了解不同设备之间的相异之处是非常重要的!
7. 阅读CDD(兼容性定义文档),了解设备可能的差异
8. 了解屏幕尺寸和密度分类(网络资料)