Android高级用户体验(一)

为不同的屏幕尺寸和密度(density)设计

参考:

http://developer.android.com/guide/practices/screens_support.html

px/dp = dpi/160

res/drawable-ldpi 大约120dpi。(注意 大约很重要~。~)

res/drawable-mdpi 大约160dpi。

res/drawable-tvdpi API Level 13引入,大约213dpi。 为电视设备的APP准备。

res/drawable-hdpi 大约240dpi。

res/drawable-xhdpi 大约320dpi。

res/drawable-nodpi 无视dpi。

不同屏幕尺寸的支持和优化

创建可扩展的布局

避免定义绝对的布局元素。

当定义UI元素的时候,比如Button和TextView,避免使用精确的大小。代替之的是使用wrap_content,match_parent

<Button 
  android:id=”@+id/button” 
  android:layout_width=”match_parent” 
  android:layout_height=”wrap_content” 
  android:text=”@string/buttonText” 
/>

Android 4.0(API 14)引入Grid Layout,一个高灵活度的布局方式,减少内嵌和简化合适和动态的布局。

为不同的屏幕尺寸优化布局

为了为不同的尺寸(注意这里讨论的是尺寸,不是什么dpi)提供合适的布局,你应该考虑创建多布局定义。

比如3inch 的QVGA和高分辨率 10.1inch的平板,一个适合横屏的布局,不一定适合竖屏。

安卓设备类别很模糊,通常设计要基于可用的空间大小,而不是设备类型。

使用long和notlong修饰符,对应着正常大小的设备和宽屏设备。

port和land修饰符来区分是否是横竖屏模式。

res/layout-long-land/          // Layouts for long screens in landscape mode.
res/layout-notlong-port/       // Layouts for not-long screens in portrait mode.

除了前面2种,android 3.2(API 13)给出了另外几个修饰符,基于当前屏幕的宽/高,或者最小的屏幕宽(宽高较小值):

res/layout-w600dp
res/layout-h720dp
res/layout-sw320dp

在早些版本的如何做呢?

答:

res/layout-small
res/layout-normal
res/layout-large
res/layout-xlarge

这是相对于normal HVGA (HVGA(320x480)  3.2inch   180dpi    mdpi)智能手机。small小于HVGA,large大于HVGA,xlarge更大于HVGA(比如平板)。

别名

创建一个res/values/layout.xml文件,使用别名去选择单面板布局。

<?xml version=”1.0” encoding=”utf-8”?> 
<resources> 
  <item name=”main” type=”layout”>@layout/main_singlepanel</item> 
</resources>

为每个应该使用多面板布局的,创建一致的values文件夹:

res/values-large-land
res/values-xlarge

然后,创建并增加一个新的layout.xml资源

<?xml version=”1.0” encoding=”utf-8”?> 
<resources> 
  <item name=”main” type=”layout”>@layout/main_multipanel</item> 
</resources>

在代码中,简单的引用R.layout.main所指向的资源,让系统自己决定选哪个。

指定支持的设备尺寸

某些APP你可能无法做到你的UI适应于所有屏幕尺寸的设备,你可以使用support-screens mainfest的元素,来指定什么样的屏幕是你能接受的。

<supports-screens android:smallScreens=”false” 
                     android:normalScreens=”true” 
                     android:largeScreens=”true” 
                     android:xlargeScreens=”true”/>

Android 3.2(API 13)引入 requiresSmallestWidthDp,compatibleWidthLimitDp,largestWidthLimitDp属性:

<supports-screens android:requiresSmallestWidthDp=”480” 
                      android:compatibleWidthLimitDp=”600” 
                      android:largestWidthLimitDp=”720”/>

创建可扩展的图像资源

Android包含了一些简单的Drawable资源类型,可以用XML定义。 其中有:ColorDrawable、ShapeDrawable和GradientDrawable类,这些资源存储在res/drawable文件夹中。

上面提到过,使用dpi分隔符运行时可以做到平稳的适配。 但是呢,像矢量图这种图形它自身可以随意缩放而不失真。但是,GradientDrawable位图是例外,需要用像素定义它的渐变半径。

在res/drawable中:

1.Corlor Drawable

<color xmlns:android=”http://schemas.android.com/apk/res/android” 
    android:color=”#FF0000” 
/>

2.Shape Drawable(对属性若有疑问,自己测试)

这种资源可以定义简单的原始形状图形。shape的属性有:

1.line 水平线,它的宽和风格由stroke来描述。

2.oval 简单的椭圆图形

3.rectangle 简单的矩形。也支持corners子节点属性,使用radius属性去创建一个有圆弧角的矩形。

4.ring 支持innerRadius和thickness属性,分别表示ring形状的内角半斤比率和厚度比率,作为其宽的一部分。(比如1/4的内部半径,可以用值:4)。

5.stroke 这个属性用来指定图形的轮廓的宽和颜色

6.padding 一会看例子

7.solid 可以用来指定背景色,color属性可用。

下面这个例子:圆角,10dp的轮廓宽,10dp的padding(绿色那部分):

<?xml version=”1.0” encoding=”utf-8”?> 
<shape xmlns:android=”http://schemas.android.com/apk/res/android” 
  android:shape=”rectangle”> 
    <solid 
       android:color=”#f0600000”/> 
    <stroke 
       android:width=”10dp” 
       android:color=”#00FF00”/> 
    <corners 
       android:radius=”15dp” /> 
    <padding 
       android:left=”10dp” 
       android:top=”10dp” 
       android:right=”10dp” 
       android:bottom=”10dp” 
    /> 
</shape>

image

接着我们介绍GradientDrawable类以及如何为Shape Drawable图形去指定填充的样子。

Gradient Drawables

Gradient Drawable能让你设计复杂的渐变填充。每个渐变定义了一个平缓的过渡在2-3种颜色,分别在线性、放射状、或者扫描模式

每个Gradient Drawable使用gradient标签定义,作为Shape Drawable定义的子节点(就像之前讨论的那些)。

每个Gradient Drawable至少需要startColor和endColor属性和可选择的middleColor

还有type属性,你可以定义以下几个:

1.linear 默认的渐变类型,画一个直接的颜色渐变,从startColor到endColor以一个角度(angle属性 可填写0-180)呈现

2.radial 画一个圆形的渐变,从startColor到endColor,从外边界到中心渐变。这个需要一个gradientRadius属性去指定渐变转化的半径(px)。还有2个可选参数,centerX和centerY属性去设置渐变的中心点。因为渐变半径是以像素PX来定义的,所以它不能动态适应不同dpi的设备。

3.sweep 扫描状的渐变,从startColor到endColor,环绕着外边界,典型的ring(耳环样子)。

下面例子,代表着res/drawable中的3个文件,一个以线性变化的矩形,一个放射状的椭圆,一个扫描状的ring:

<!-- Rectangle with linear gradient --> 
<?xml version=”1.0” encoding=”utf-8”?> 
<shape xmlns:android=”http://schemas.android.com/apk/res/android” 
   android:shape=”rectangle” 
   android:useLevel=”false”> 
   <gradient 
     android:startColor=”#ffffff” 
     android:endColor=”#ffffff” 
     android:centerColor=”#000000” 
     android:useLevel=”false” 
     android:type=”linear” 
     android:angle=”45” 
   /> 
</shape>

<!-- Oval with radial gradient --> 
<?xml version=”1.0” encoding=”utf-8”?> 
<shape xmlns:android=”http://schemas.android.com/apk/res/android” 
   android:shape=”oval” 
   android:useLevel=”false”> 
   <gradient 
     android:type=”radial” 
     android:startColor=”#ffffff” 
     android:endColor=”#ffffff” 
     android:centerColor=”#000000” 
     android:useLevel=”false” 
     android:gradientRadius=”300” 
   /> 
</shape>

<!-- Ring with sweep gradient --> 
<?xml version=”1.0” encoding=”utf-8”?> 
<shape xmlns:android=”http://schemas.android.com/apk/res/android” 
   android:shape=”ring” 
   android:useLevel=”false” 
   android:innerRadiusRatio=”3” 
   android:thicknessRatio=”8”> 
   <gradient 
     android:startColor=”#ffffff” 
     android:endColor=”#ffffff” 
     android:centerColor=”#000000” 
     android:useLevel=”false” 
     android:type=”sweep” 
   /> 
</shape>

image效果图!

高级Drawable资源

可变化的Drawables

ScaleDrawable  scaleHeight,scaleWidth表示缩放的百分比,scaleGravity设置锚点。

<?xml version=”1.0” encoding=”utf-8”?> 
<scale xmlns:android=”http://schemas.android.com/apk/res/android” 
   android:drawable=”@drawable/icon”

   android:scaleHeight=”100%” 
   android:scaleWidth=”100%” 
   android:scaleGravity=”center_vertical|center_horizontal” 
/>

RotateDrawable 下面这个意思就是,从0度到90的旋转,中心点分别是X,Y上的50%。

<?xml version=”1.0” encoding=”utf-8”?> 
<rotate xmlns:android=”http://schemas.android.com/apk/res/android” 
   android:drawable=”@drawable/icon” 
   android:fromDegrees=”0” 
   android:toDegrees=”90” 
   android:pivotX=”50%” 
   android:pivotY=”50%” 
/>

运行时如何运用缩放和旋转呢?

答:使用setImageLevel方法在View对象,变换图片在0-10,000之间,对应着0-100%,默认是0.

ImageView rotatingImage 
   = (ImageView)findViewById(R.id.RotatingImageView); 
ImageView scalingImage 
   = (ImageView)findViewById(R.id.ScalingImageView);

// Rotate the image 50% of the way to its final orientation. 
rotatingImage.setImageLevel(5000);

// Scale the image to 50% of its final size. 
scalingImage.setImageLevel(5000);

Layer Drawables(不介绍了)

<?xml version=”1.0” encoding=”utf-8”?> 
<layer-list xmlns:android=”http://schemas.android.com/apk/res/android”> 
  <item android:drawable=”@drawable/bottomimage”/> 
  <item android:drawable=”@drawable/image2”/> 
  <item android:drawable=”@drawable/image3”/> 
  <item android:drawable=”@drawable/topimage”/> 
</layer-list>

最上面的条目放在最底层。

State List Drawables(不介绍了)

<selector xmlns:android=”http://schemas.android.com/apk/res/android”> 
  <item android:state_pressed=”true” 
          android:drawable=”@drawable/widget_bg_pressed”/> 
  <item android:state_focused=”true” 
          android:drawable=”@drawable/widget_bg_selected”/> 
  <item android:state_window_focused=”false” 
          android:drawable=”@drawable/widget_bg_normal”/> 
  <item android:drawable=”@drawable/widget_bg_normal”/> 
</selector>

android:state_pressed—是否被按下

android:state_focused— 是否获得焦点

android:state_hovered— API 11引入,判断鼠标是不是盘旋在视图上。

android:state_selected— 是否被选中。

android:state_checkable— 是否可被选中。

android:state_checked— 是否被选中。

android:state_enabled— 是否可用

android:state_activated— 是否在激活状态。

android:state_window_focused— 父窗口是否获得焦点。

 

Level List Drawables

使用Level List Drawable你可以创建一个Drawable资源数组,为每层设定一个整形的索引值。使用level-list节点去创建一个新的Level List Drawable,使用item子节点去定义每层,附上android: drawable/android:maxLevel属性。

<level-list xmlns:android=”http://schemas.android.com/apk/res/android”> 
  <item android:maxLevel=”0”  android:drawable=”@drawable/earthquake_0”/> 
  <item android:maxLevel=”1”  android:drawable=”@drawable/earthquake_1”/> 
  <item android:maxLevel=”2”  android:drawable=”@drawable/earthquake_2”/> 
  <item android:maxLevel=”4”  android:drawable=”@drawable/earthquake_4”/> 
  <item android:maxLevel=”6”  android:drawable=”@drawable/earthquake_6”/> 
  <item android:maxLevel=”8”  android:drawable=”@drawable/earthquake_8”/> 
  <item android:maxLevel=”10” android:drawable=”@drawable/earthquake_10”/> 
</level-list>

程序中,选择哪张图片去显示,通过调用View的 setImageLevel方法,传入 Drawable的索引值

imageView.setImageLevel(5);

View会显示与指定的索引值一致或者大于这个指定的索引值的一张图片。

转载于:https://my.oschina.net/wangjunhe/blog/114039

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值