当前位置: 58彩票app下载 > 编程技术 > 正文

Android样式研究

时间:2019-09-18 11:14来源:编程技术
今天我们来探究一下android的样式。其实,几乎所有的控件都可以使用background属性去引用自定义的XML样式,所以研究样式显得特别重要。先来看一段样式代码: Drawable简介 提到Drawable,

今天我们来探究一下android的样式。其实,几乎所有的控件都可以使用 background属性去引用自定义的XML样式,所以研究样式显得特别重要。先来看一段样式代码:

Drawable简介

提到Drawable,第一反应肯定是存放图片的位置,实际上,Drawable并不仅仅指图片。它可以理解为一种图片的概念,比如颜色填充,也可以理解为一种图片。

Drawable类是一个抽象类,它有BitmapDrawable,ShapeDrawable,LayerDrawable,StateListDrawable等常用子类。

<?xml version="1.0" encoding="utf-8"?><selector xmlns:andro> <item> <shape android:innerRadiusRatio="10" android:shape="ring" android:thicknessRatio="9" android:useLevel="false"> <stroke android:width="1dp" android:color="@android:color/black" /> </shape> </item></selector>

BitmapDrawable

BitmapDrawable就是一张图片,通过src属性定义指向的图片资源,然后对该图片进行相关设置主要属性如下:

<pre>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"
android:gravity="bottom"//设定图片在容器中的位置,默认值为fill,在水平和竖直方向填充容器
android:antialias="true"//设置抗锯齿
android:tint 给图片着色,比如图片本来是黑色的,着色后可以变成白色
android:tintMode 着色模式,也是API Level 21(Android 5.0)才添加的属性
android:alpha 设置图片的透明度,取值范围为0.0~1.0之间,API Level最低要求是11,即Android 3.0
android:filter="true"//开启过滤效果
android:dither="true"//开启抖动效果
android:tileMode="clamp"//设置平铺方式,disable,clamp,repeat,mirror

</bitmap>
//使用代码进行动态设置:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
bitmapDrawable.setTileModeXY(Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bitmapDrawable.setAntiAlias(true);
bitmapDrawable.setDither(true);
</pre>

除了针对常见图片的BitmapDrawable之外,NinePatchDrawable对应的是.9图片,用法同BitmapDrawable一样,根标签是nine-patch

说一下一些基本的知识:(我也是刚刚才知道的)

ColorDrawable

ColorDrawable用纯色填充一块区域,使用也最简单,只有一个属性,color:

<pre>
<color xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorBlack">
</color>
//代码设定:
ColorDrawable colorDrawable = new ColorDrawable(0xffff0000);
//使用颜色:
mImageView.setBackground(new ColorDrawable(0xffff0000));
mImageView.setBackgroundColor(Color.argb(255,00,255,00));
</pre>

Android中对颜色的设定采用ARGB模式,xml中可以不指定alpha值,但是在代码中使用十六进制数值设置颜色时,必须制定alpha值,否则默认为0x00,全透明,是看不到颜色的。

<?xml version="1.0" encoding="utf-8"?>

GradientDrawable(ShapeDrawable)

GradientDrawable表示一个渐变区域,可以实现线性渐变、发散渐变、和平铺渐变。它的主要属性如下:

<pre>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">//设置Shape形状,rectangle(矩形),oval(椭圆),line(直线),ring(圆形)四个可选值

<corners //只有rectangle有效,用来设置四个角的圆角半径
    android:radius="50px"//对四个角统一设置,优先级较低,会被以下属性覆盖
    android:topLeftRadius="40dp"
    android:topRightRadius="40dp"
    android:bottomLeftRadius="40dp"
    android:bottomRightRadius="40dp"/>
<gradient//渐变效果
    android:angle="45"//渐变的方向角度,必须为45的倍数,默认为0
    android:centerX="100"//渐变中心点X坐标
    android:centerY="250"
    android:startColor="@color/colorBlack"//渐变起始色
    android:centerColor="@color/colorDarkGreen"//渐变中间颜色
    android:endColor="@color/colorWhite"//结束颜色
    android:gradientRadius="50dp"//渐变半径,只有type值为radial时有效
    android:type="linear"//渐变类型,有Linear(线性),radial(径向),sweep(扫描线)三种。默认为线型渐变
    android:useLevel="false"/>//一般为false,只有当Drawable作为StateListDrawable使用才设置true
<solid//纯色填充,与gradient互斥
    android:color="@color/colorDarkGreen"/>
<stroke//Shape描边效果
    android:width="5dp"//描边宽度
    android:color="@color/colorLightRed"
    android:dashWidth="15dp"//线条长度
    android:dashGap="5dp"/>//线条间距
<padding//设置内边距
    android:left="5dp"
    android:right="5dp"
    android:bottom="5dp"
    android:top="5dp"/>
<size//设置尺寸。Drawable本身是没有尺寸概念的,使用getIntrinsicWidth/Height获取到的值是-1。通过Size设定Drawable固有尺寸。
        但是作为背景的时候,Shape仍然会拉伸为适合view的大小
    android:width="200dp"
    android:height="200dp"/>

</shape>
</pre>

  • 这个是声明了XML的版本信息为1.0,字符编码为UTF-8

LayerDrawable

LayerDrawable包含多个item,每个item表示一个drawable,LayerDrawable将所包含的item放置在不同的层次上,第一个item在最底层,依次向上叠加:

<pre>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="2dp"
android:top="4dp">
<shape>
<solid android:color="@android:color/darker_gray" />
<corners android:radius="10dp" />
</shape>
</item>
<item
android:bottom="4dp"
android:right="2dp">
<shape>
<solid android:color="#FFFFFF" />
<corners android:radius="10dp" />
</shape>
</item>
</layer-list>
</pre>

item子节点可以直接定义一个Drawable,也可以使用android:drawable属性来引用一个Drawable,layer-list没有属性节点,只包含Item子节点。Item节点属性除了android:drawable,还有android:top/left/right/bottom用来设定各个方向的偏移距离

xmlns:andro

StateListDrawable

StatelistDrawable也是一个Drawable集合,每个Drawable对应View的一种状态,只要用在设置View的背景。它使用selector标签:

<pre>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true" //默认为false。因为状态改变的时候会切换到不同的Drawable,大小也是不同的,设置为true表示尺寸固定不变
android:dither="true"
android:variablePadding="true"//默认为false,表示padding不随着状态的改变而变化。
android:enterFadeDuration="500"//状态改变时切入的动作事件,ms
android:exitFadeDuration="500">
<item
android:drawable="@color/colorBlack"//指定Drawable资源,也可以是color
android:state_pressed="true"//按下状态
android:state_focused="true"//获取到焦点
android:state_hovered="true"//API14加入,true表示鼠标在其上滑动
android:state_selected="true"//选择了view
android:state_checkable="true"//可选择状态。类似于enable,它用来设置CheckBox等可勾选的控件
android:state_checked="true"//是否选中状态
android:state_enabled="false"//是否可用状态。通常只设置false
android:state_activated="true"/是否被激活状态,API Level 11及以上才支持,可通过代码调用控件的setActivated(boolean)方法设置是否激活该控件
android:state_window_focused="true"/>//当前窗口是否获取焦点。比如弹出对话框就会失去焦点
</selector>
</pre>

系统会根据View的当前状态从selector中选择对应的item,选择的时候会从上向下一直找到第一条匹配的item,通常会设置一个默认的item放在最后,不设置任何的状态。这样当系统在上边的item中找不到对应的状态时,就会选择最后一个默认的item,它不附带任何状态,可以匹配给所以状态。

<pre>
<selector xmlns:android=";

<item android:color="@android:color/black" android:state_window_focused="false" />

<item android:color="@android:color/background_light" android:state_enabled="false" />

<item android:color="@android:color/holo_blue_light" android:state_pressed="true" />

<item android:color="@android:color/holo_green_dark" android:state_selected="true" />

<item android:color="@android:color/holo_green_light" android:state_activated="true" />

<item android:color="@android:color/white" />
</selector>
//在控件中使用Drawable
<Button
android:id="@+id/btn_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@drawable/bg_btn_selector"
android:text="默认按钮"
android:textColor="@color/text_btn_selector" />
</pre>

  • 这个是XML的命名空间,也就是有了它,你可以 ==alt+/== 作为提示,不该输入什么,什么是对的,什么是错的。

LevelListDrawable

LevelListDrawable也是一系列Drawable集合,它通过Level来匹配item。

<pre>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@color/colorBlack"
android:maxLevel="10000"
android:minLevel="0"/>
</level-list>
</pre>

item子节点除了指定Drawable之外,只有两个属性android:maxLevel指定最高Level(10000),android:minLevel指定最低Level(0),在这两个值中间就会匹配该item。匹配的时候也是从上向下,直到匹配到一条合适的item 。所以,通常只需要指定maxLevel就可以了,将item按maxLevel从小到大依次排列下来。

Level的设置使用Drawable的setLevel方法来设定。如果是作为ImageView的前景,也可以通过ImageView的setImageLevel来设定。

android:visiable

TransitionDrawable

transition其实是继承自layer-list的,只是,transition只能管理两层drawable,另外提供了两层drawable之间切换的方法,切换时还会有淡入淡出的动画效果。示例代码如下:

<pre>
<transition xmlns:android=";
<item android:drawable="@drawable/on" />
<item android:drawable="@drawable/off" />
</transition>
</pre>

然后在控件中指定背景:

<pre>
<Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/transition_drawable"
/>
</pre>

transition标签生成的Drawable对应的类为TransitionDrawable,要切换时,需要主动调用TransitionDrawable的startTransition()方法,参数为动画的毫秒数,也可以调用reverseTransition()方法逆向切换。

<pre>
Button mButton = (Button) findViewById(R.id.btn1);
TransitionDrawable transitionDrawable = mButton.getBackground();
transitionDrawable.startTransition(500); //正向切换,即从第一个drawable切换到第二个
transitionDrawable.reverseTransition(500); //逆向切换,即从第二个drawable切换回第一个
</pre>

  • true设置该效果改样式可见

InsetDrawable

InsetDrawable使用<inset>标签,可以将指定的Drawable内嵌到自己当中,特殊的是它可以设置四周的间距,作为背景时,设定值为背景与view边框的距离,用layerList同样可以实现。

<pre>
android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
android:visible 设置初始的可见性状态,默认为false
android:insetLeft 左边距
android:insetRight 右边距
android:insetTop 顶部边距
android:insetBottom 底部边距
android:inset 设置统一边距,会覆盖上面四个属性,但API Level要求为21,即Android 5.0
</pre>

android:autoMirrored

ScaleDrawable

ScaleDrawable使用<scale>标签,它可以对指定的drawable进行缩放。它的scaleGravity属性作用同BItmap一样。另外还有两个特殊属性,scaleHeight和scaleWidt指定宽和高的缩放比例,接收百分比数值。需要注意的是,ScaleDrawable缩放效果不仅仅受scaleHeight和scaleWidth影响,还要指定Level。默认的Level为0,这时候ScaleDrawable是不会绘制的。下面来看一个例子:

<pre>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:scaleGravity="center"
android:scaleHeight="30%"//实际大小约为70%
android:scaleWidth="30%"
android:level="1"/>//API 24以上才支持
//在控件中使用:这时候是看不到图片的,没有设置Level,图片不会绘制出来
<ImageView
android:id="@+id/scaleimg"
android:src="@drawable/scaledraw"
android:layout_width="150dp"
android:layout_height="150dp"/>
//设置Level:
mScaleImageView.setImageLevel(1);
</pre>

注意的是,Level对缩放比例的影响,Level值越大,Drawable就越大,如果设置为10000(Level最大值),那么不管缩放比例设置多少,都不会进行缩放。而scaleHeight和scaleWidth相反,值越大,Drawable越小。

  • true设置单行显示,例如是TextView有多行文字,那么只显示一行,后面显示...

ClipDrawable

ClipDrawable用来对Drawable进行裁剪,它也是根据Level来决定裁剪范围,10000表示不裁剪,0表示全部裁剪,就看不到了。裁剪的方向通过clipOritation来设置vertical和horizontal,除此之外还有一个Gravity属性,它和clipOritation一起决定了裁剪方式。
Gravity有以下取值:

top: Drawable放在容器顶部,竖直裁剪的时候从底部开始
bottom:Drawable放在容器底部,竖直裁剪时从顶部开始
left:默认值。Drawable放在容器左边,水平裁剪时从右边开始
right:放在右边,水平裁剪从左边开始
center_vertical:Drawable竖直居中,不改变大小,竖直裁剪从上下同时开始
fill_vertical:竖直方向填充容器。竖直裁剪的时候,只有clipDrawable的level为0,才有裁剪行为
center_horizontal:水平居中,不改变大小,水平裁剪从左右同时开始
fill_horizontal:水平填充,水平裁剪只有当clipDrawable的level为0,才有裁剪行为
center:水平和垂直居中,竖直方向上下,水平方向左右同时裁剪
fill:水平和竖直方向填充容器,只有当clipDrawable的level为0,才有裁剪行为

android:constantSize

其他标签

  • rotate
    <rotate>标签用来控制Drawable的旋转,主要用以下属性:

    android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
    android:fromDegrees 起始的角度度数
    android:toDegrees 结束的角度度数,正数表示顺时针,负数表示逆时针
    android:pivotX 旋转中心的X坐标,浮点数或是百分比。浮点数表示相对于drawable的左边缘距离单位为px,如5; 百分比表示相对于drawable的左边缘距离按百分比计算,如5%; 另一种百分比表示相对于父容器的左边缘,如5%p; 一般设置为50%表示在drawable中心

android:pivotY 旋转中心的Y坐标
android:visible 设置初始的可见性状态,默认为false

将一张图片旋转180度代码如下:

<pre>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_arrow"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="180" />
</pre>

rotate同样与Level有关。Level值从0-10000分别对应fromDegrees和toDegrees,比如Level设置5000就会旋转90度。因为level值默认为0,所以默认是不会旋转的,如果要旋转的话可以将android:fromDegrees直接设置180度,开始的状态就已经完成旋转了。

  • animation-list
    <animation-list>用来将一系列drawable构建成帧动画。通过添加item子标签设置每一帧使用的drawable资源,以及每一帧持续的时间。示例代码如下:

    <pre>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
    android:drawable="@drawable/anim1"
    android:duration="1000" />
    <item
    android:drawable="@mipmap/anim2"
    android:duration="1000" />
    <item
    android:drawable="@mipmap/anim3"
    android:duration="1000" />
    </animation-list>
    </pre>

    android:oneshot属性设置是否循环播放,设为true时,只播放一轮就结束,设为false时,则会轮询播放。
    android:duration属性设置该帧持续的时间,以毫秒数为单位。
    animation-list对应的Drawable类为AnimationDrawable,要让动画运行起来,需要主动调用AnimationDrawable的start()方法。另外,如果在Activity的onCreate()方法里直接调用start()方法会没有效果,因为view还没有初始化完成是播放不了动画的。

  • animation-rotate

    rotate标签只是将原有的drawable转个角度变成另一个drawable,它是静态的。而animated-rotate则会让drawable不停地做旋转动画。
    animated-rotate可设置的属性只有四个:

android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
android:pivotX 旋转中心的X坐标
android:pivotY 旋转中心的Y坐标
android:visible 设置初始的可见性状态,默认为false

示例代码:
<pre>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/img_daisy"
android:pivotX="50%"
android:pivotY="50%"
android:visible="false" />
</pre>

  • 这个是布尔型,false表示各个状态的大小各自不同,true表中所有的状态大小相同。默认为false

android:dither

  • 图像的抖动处理,当每个颜色值以低于8位表示时,对应图像做抖动处理可以实现在可显示颜色总数比较低时还保持较好的显示效

android:enterFadeDuration

  • 表示样式淡入的时间,毫秒

android:exitFadeDuration

  • 表示样式淡出的时间,毫秒

android:variablePadding

  • 布尔型。选择true时,drawable的内边距会根据状态的变化而变化,设置为true时,你必须为不同的状态配置layout,但是通常不建议这么做。选择false时,内边距保持一致,所有状态中最大的内边距。默认为false

selector标签下只有item标签。item的标签内属性如下:

都是设置控件在什么状态下的样式:

android:drawable 需要入别的xml,默认是背景图片android:state_above_achorandroid:state_accelerated 硬件加速true时的效果android:state_activated true被激活时的效果,false未激活时的效果android:state_active true激活后的效果android:state_checkable true,当CheckBox能使用时显示该图片android:state_checked true,当CheckBox选中时显示该图片android:state_drag_can_accept true 能够 drag 拖拽时图片android:state_drag_hovered true 能够 drag 鼠标指针移动到该位置图片android:state_emptyandroid:state_enabled true,当该组件能使用时显示该图片android:state_expandedandroid:state_firstandroid:state_****focused true非触摸模式下获得焦点时显示图片android:state_hovered 鼠标移动到该位置时的样式android:state_lastandroid:state_long_pressable 长按的样式android:state_middleandroid:state_multilineandroid:state_pressed 按下的样式android:state_selected 选择时的样式android:state_single true 只有一个元素显示图片android:state_window_focused 当此activity获得焦点在最前面时显示该图片

  • color 设置颜色
  • animated-rotate
  • animated-selector
  • animation-list
  • bitmap
  • clip
  • inset
  • layer-list
  • level-list
  • nine-patch
  • ripple
  • rotate
  • scale
  • selector
  • set
  • shape
  • transition

shape标签:

标签内属性:

  • visible 是否可见
  • dither 图像的抖动处理,当每个颜色值以低于8位表示时,对应图像做抖动处理可以实现在可显示颜色总数比较低时还保持较好的显示效果
  • innerRadius
  • innerRadiusRatio
  • shape 指定画的图形
  • thickness
  • thicknessRatio
  • useLevel

shape=rectangle: 矩形,默认的形状,可以画出直角矩形、圆角矩形、弧形等

  • solid: 设置形状填充的颜色,只有android:color一个属性--android:color 填充的颜色

  • padding: 设置内容与形状边界的内间距,可分别设置左右上下的距离--android:left 左内间距--android:right 右内间距--android:top 上内间距--android:bottom 下内间距

  • gradient: 设置形状的渐变颜色,可以是线性渐变、辐射渐变、扫描性渐变--android:type 渐变的类型--linear 线性渐变,默认的渐变类型--radial 放射渐变,设置该项时,android:gradientRadius也必须设置--sweep 扫描性渐变--android:startColor 渐变开始的颜色--android:endColor 渐变结束的颜色--android:centerColor 渐变中间的颜色--android:angle 渐变的角度,线性渐变时才有效,必须是45的倍数,0表示从左到右,90表示从下到上--android:centerX 渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间--android:centerY 渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间--android:gradientRadius 渐变的半径,只有渐变类型为radial时才使用--android:useLevel 如果为true,则可在LevelListDrawable中使用

  • corners: 设置圆角,只适用于rectangle类型,可分别设置四个角不同半径的圆角,当设置的圆角半径很大时,比如200dp,就可变成弧形边了--android:radius 圆角半径,会被下面每个特定的圆角属性重写--android:topLeftRadius 左上角的半径--android:topRightRadius 右上角的半径--android:bottomLeftRadius 左下角的半径--android:bottomRightRadius 右下角的半径

  • stroke: 设置描边,可描成实线或虚线。--android:color 描边的颜色--android:width 描边的宽度--android:dashWidth 设置虚线时的横线长度,0为实线--android:dashGap 设置虚线时的横线之间的距离,即虚线的间隔大小

  • size:设置组件大小--android:width 组件宽--android:height 组件高

shape=oval: 椭圆形,用得比较多的是画正圆

主要是通过设置padding和size去实现圆的大小,扁正。
  • corners 圆角
  • gradient 渐变色
  • padding 内边距
  • size 组件大小
  • solid 设置形状填充的颜色
  • stroke 描边
  1. 注意,使用radial渐变时,必须指定渐变的半径,即android:gradientRadius属性。

shape=line: 线形,可以画实线和虚线

line主要用于画分割线,是通过stroke和size特性组合来实现的
  • corners 圆角
  • gradient 渐变色
  • padding 内边距
  • size 组件大小
  • solid 设置形状填充的颜色
  • stroke 描边

画线时,有几点特性必须要知道的:

  1. 只能画水平线,画不了竖线;
  2. 线的高度是通过stroke的android:width属性设置的;
  3. size的android:height属性定义的是整个形状区域的高度;
  4. size的height必须大于stroke的width,否则,线无法显示;
  5. 线在整个形状区域中是居中显示的;
  6. 线左右两边会留有空白间距,线越粗,空白越大;
  7. 引用虚线的view需要添加属性android:layerType,值设为”software”,否则显示不了虚线。

shape=ring: 环形,可以画环形进度条

首先,shape根元素有些属性只适用于ring类型,先过目下这些属性吧:android:innerRadius 内环的半径android:innerRadiusRatio 浮点型,以环的宽度比率来表示内环的半径,默认为3,表示内环半 径为环的宽度除以3,该值会被android:innerRadius覆盖android:thickness 环的厚度android:thicknessRatio 浮点型,以环的宽度比率来表示环的厚度,默认为9,表示环的厚度为环的宽度除以9,该值会被android:thickness覆盖android:useLevel 一般为false,否则可能环形无法显示,只有作为LevelListDrawable使用时才设为true
  • corners 圆角
  • gradient 渐变色
  • padding 内边距
  • size 组件大小
  • solid 设置形状填充的颜色
  • stroke 描边

layer-list标签:

layer-list经过一系列的item标签,从上到下的顺序,从低到上把item的效果叠加起来。

layer-list可以作为根节点,也可以作为selector中item的子节点。layer-list可以添加多个item子节点,每个item子节点对应一个drawable资源,按照item从上到下的顺序叠加在一起,再通过设置每个item的偏移量就可以看到阴影等效果了。layer-list的item可以通过下面四个属性设置偏移量:

android:top 顶部的偏移量android:bottom 底部的偏移量android:left 左边的偏移量android:right 右边的偏移量

这四个偏移量和控件的margin设置差不多,都是外间距的效果。如何不设置偏移量,前面的图层就完全挡住了后面的图层,从而也看不到后面的图层效果了。比如上面的例子,Tab背景中的白色背景设置了android:bottom之后才能看到一点红色背景。那么如果偏移量设为负值会怎么样呢?经过验证,偏移超出的部分会被截掉而看不到,不信可以自己试一下。有时候这很有用,比如当我想显示一个半圆的时候。

另外,关于item的用法,也做下总结:

根节点不同时,可设置的属性是会不同的,比如selector下,可以设置一些状态属性,而在layer-list下,可以设置偏移量;就算父节点同样是selector,放在drawable目录和放在color目录下可用的属性也会不同,比如drawable目录下可用的属性为android:drawable,在color目录下可用的属性为android:color;item的子节点可以为任何类型的drawable类标签,除了上面例子中的shape、color、layer-list,也可以是selector,还有其他没讲过的bitmap、clip、scale、inset、transition、rotate、animated-rotate、lever-list等等。

for example,以下是一个白色背景,有灰色阴影的矩形框。

<?xml version="1.0" encoding="utf-8"?><selector xmlns:andro> <item> <layer-list> <!-- 灰色阴影 --> <item android:left="1dp" android:top="2dp"> <shape> <size android:width="20dp" android:height="10dp"/> <solid android:color="@android:color/darker_gray" /> <corners android:radius="10dp" /> </shape> </item> <!-- 白色前景 --> <item android:bottom="2dp" android:right="1dp"> <shape> <solid android:color="#FFFFFF" /> <corners android:radius="10dp" /> </shape> </item> </layer-list> </item></selector>

bitmap标签

主要可以通过bitmap标签对图片做一些设置,如平铺、拉伸或保持图片原始大小,也可以指定对齐方式。
  • android:src 必填项,指定图片资源,只能是图片,不能是xml定义的drawable资源
  • android:gravity 设置图片的对齐方式,比如在layer-list中,默认会尽量填满整个视图,导致图片可能会被拉伸,为了避免被拉伸,就可以设置对齐方式,可取值为下面的值,多个取值可以用 | 分隔:--top 图片放于容器顶部,不改变图片大小--bottom 图片放于容器底部,不改变图片大小--left 图片放于容器左边,不改变图片大小--right 图片放于容器右边,不改变图片大小--center 图片放于容器中心位置,包括水平和垂直方向,不改变图片大小--fill 拉伸整张图片以填满容器的整个高度和宽度,默认值--center_vertical 图片放于容器垂直方向的中心位置,不改变图片大小--center_horizontal 图片放于容器水平方向的中心位置,不改变图片大小--fill_vertical 在垂直方向上拉伸图片以填满容器的整个高度--fill_horizontal 在水平方向上拉伸图片以填满容器的整个宽度--clip_vertical 附加选项,裁剪基于垂直方向的gravity设置,设置top时会裁剪底部,设置bottom时会裁剪顶部,其他情况会同时裁剪顶部和底部--clip_horizontal 附加选项,裁剪基于水平方向的gravity设置,设置left时会裁剪右侧,设置right时会裁剪左侧,其他情况会同时裁剪左右两侧
  • android:antialias 设置是否开启抗锯齿
  • android:dither 设置是否抖动,图片与屏幕的像素配置不同时会用到,比如图片是ARGB 8888的,而屏幕是RGB565
  • android:filter 设置是否允许对图片进行滤波,对图片进行收缩或者延展使用滤波可以获得平滑的外观效果
  • android:tint 给图片着色,比如图片本来是黑色的,着色后可以变成白色
  • android:tileMode 设置图片平铺的方式,取值为下面四种之一:--disable 不做任何平铺,默认设置--repeat 图片重复铺满--mirror 使用交替镜像的方式重复图片的绘制--clamp 复制图片边缘的颜色来填充容器剩下的空白部分,比如引入的图片如果是白色的边缘,那么图片所在的容器里除了图片,剩下的空间都会被填充成白色
  • android:alpha 设置图片的透明度,取值范围为0.0~1.0之间,0.0为全透明,1.0为全不透明,API Level最低要求是11,即Android 3.0
  • android:mipMap 设置是否可以使用mipmap,但API Level最低要求是17,即Android 4.2
  • android:autoMirrored 设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API Level 19(Android 4.4)才添加的属性
  • android:tileModeX 和tileMode一样设置图片的平铺方式,只是这个属性只设置水平方向的平铺方式,这是API Level 21(Android 5.0)才添加的属性
  • android:tileModeY 和tileMode一样设置图片的平铺方式,只是这个属性只设置垂直方向的平铺方式,这是API Level 21(Android 5.0)才添加的属性
  • android:tintMode 着色模式,也是API Level 21(Android 5.0)才添加的属性

nine-patch标签

点九图片文件扩展名为:.9.png,通过点九图片可以做局部拉伸,比如,一张圆角矩形图片,我们不想让它的四个边角都被拉伸从而导致模糊失真,使用点九图就可以控制拉伸区域,让四个边角保持完美显示。画点九图一般用Android SDK工具集里的draw9patch工具,只需要在四条边画黑线就可以了,

使用nine-patch标签可以对点九图片做一些设置处理,不过可设置的属性并不多:

  • android:src 必填项,必须指定点九类型的图片
  • android:dither 设置是否抖动,图片与屏幕的像素配置不同时会用到,比如图片是ARGB 8888的,而屏幕是RGB565
  • android:tint 给图片着色,比如图片本来是黑色的,着色后可以变成白色
  • android:tintMode 着色模式,API Level 21(Android 5.0)才添加的属性
  • android:alpha 设置图片的透明度,取值范围为0.0~1.0之间,0.0为全透明,1.0为全不透明,API Level最低要求是11
  • android:autoMirrored 设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API Level 19(Android 4.4)才添加的属性

color标签

color标签是drawable里最简单的标签了,只有一个属性:android:color,指定颜色值。这个标签一般很少用,因为基本都可以通过其他更方便的方式定义颜色。另外,颜色值一般都在colors.xml文件中定义,其根节点为resources。

inset标签

使用inset标签可以对drawable设置边距,其用法和View的padding类似,只不过padding是设置内容与边界的距离,而inset则可以设置背景drawable与View边界的距离。inset标签的可设置属性如下:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
  • android:visible 设置初始的可见性状态,默认为false
  • android:insetLeft 左边距
  • android:insetRight 右边距
  • android:insetTop 顶部边距
  • android:insetBottom 底部边距
  • android:inset 设置统一边距,会覆盖上面四个属性,但API Level要求为21,即Android 5.0

clip标签

使用clip标签可以对drawable进行裁剪,在做进度条时很有用。通过设置level值控制裁剪多少,level取值范围为0~10000,默认为0,表示完全裁剪,图片将不可见;10000则完全不裁剪,可见完整图片。看看clip标签可以设置的属性:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签

  • android:clipOrientation 设置裁剪的方向,取值为以下两个值之一:--horizontal 在水平方向上进行裁剪,条状的进度条就是水平方向的裁剪--vertical 在垂直方向上进行裁剪

  • android:gravity 设置裁剪的位置,可取值如下,多个取值用 | 分隔:--top 图片放于容器顶部,不改变图片大小。当裁剪方向为vertical时,会裁掉图片底部--bottom 图片放于容器底部,不改变图片大小。当裁剪方向为vertical时,会裁掉图片顶部--left 图片放于容器左边,不改变图片大小,默认值。当裁剪方向为horizontal,会裁掉图片右边部分--right 图片放于容器右边,不改变图片大小。当裁剪方向为horizontal,会裁掉图片左边部分--center 图片放于容器中心位置,包括水平和垂直方向,不改变图片大小。当裁剪方向为horizontal时,会裁掉图片左右部分;当裁剪方向为vertical时,会裁掉图片上下部分--fill 拉伸整张图片以填满容器的整个高度和宽度。这时候图片不会被裁剪,除非level设为了0,此时图片不可见--center_vertical 图片放于容器垂直方向的中心位置,不改变图片大小。裁剪和center时一样--center_horizontal 图片放于容器水平方向的中心位置,不改变图片大小。裁剪和center时一样--fill_vertical 在垂直方向上拉伸图片以填满容器的整个高度。当裁剪方向为vertical时,图片不会被裁剪,除非level设为了0,此时图片不可见--fill_horizontal 在水平方向上拉伸图片以填满容器的整个宽度。当裁剪方向为horizontal时,图片不会被裁剪,除非level设为了0,此时图片不可见--clip_vertical 附加选项,裁剪基于垂直方向的gravity设置,设置top时会裁剪底部,设置bottom时会裁剪顶部,其他情况会同时裁剪顶部和底部--clip_horizontal 附加选项,裁剪基于水平方向的gravity设置,设置left时会裁剪右侧,设置right时会裁剪左侧,其他情况会同时裁剪左右两侧

level的设置需要在代码中动态去设置:

1 . 定义clip.xml:

<?xml version="1.0" encoding="utf-8"?><clip xmlns:andro android:clipOrientation="horizontal" android:drawable="@drawable/img4clip" android:gravity="left" />

2 . 在ImageView中引用:

<ImageView android: android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_img" android:src="@drawable/clip" />

3 . 在代码中设置level:

ImageView img = (ImageView) findViewById;``img.getDrawable().setLevel; //level范围值0~10000

scale标签

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
  • android:scaleHeight 设置可缩放的高度,用百分比表示,格式为XX%,0%表示不做任何缩放,50%表示只能缩放一半
  • android:scaleWidth 设置可缩放的宽度,用百分比表示,格式为XX%,0%表示不做任何缩放,50%表示只能缩放一半
  • android:scaleGravity 设置drawable缩放后的位置,取值和bitmap标签的一样,就不一一列举说明了,不过默认值是left
  • android:useIntrinsicSizeAsMinimum 设置drawable原有尺寸作为最小尺寸,设为true时,缩放基本无效,API Level最低要求为11使用的时候,和clip一样,在代码中设置level

level-list标签

当需要在一个View中显示不同图片的时候,比如手机剩余电量不同时显示的图片不同,level-list就可以派上用场了。level-list可以管理一组drawable,每个drawable设置一组level范围,最终会根据level值选取对应的drawable绘制出来。level-list通过添加item子标签来添加相应的drawable,其下的item只有三个属性:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
  • android:minLevel 该item的最小level值
  • android:maxLevel 该item的最大level值以下是示例代码:
<?xml version="1.0" encoding="utf-8"?><level-list xmlns:andro> <item android:drawable="@drawable/battery_low" android:maxLevel="10" android:minLevel="0" /> <item android:drawable="@drawable/battery_below_half" android:maxLevel="50" android:minLevel="10" /> <item android:drawable="@drawable/battery_over_half" android:maxLevel="99" android:minLevel="50" /> <item android:drawable="@drawable/battery_full" android:maxLevel="100" android:minLevel="100" /></level-list>

那么,当电量剩下10%时则可以设置level值为10,将会匹配第一张图片:

img.getDrawable().setLevel;

item的匹配规则是从上到下的,当设置的level值与前面的item的level范围匹配,则采用。一般item的添加按maxLevel从小到大排序下来,此时minLevel可以不用指定也能匹配到。如上面代码就可以简化如下:

<?xml version="1.0" encoding="utf-8"?><level-list xmlns:andro> <item android:drawable="@drawable/battery_low" android:maxLevel="10" /> <item android:drawable="@drawable/battery_below_half" android:maxLevel="50" /> <item android:drawable="@drawable/battery_over_half" android:maxLevel="99" /> <item android:drawable="@drawable/battery_full" android:maxLevel="100" /></level-list>

但不能反过来将android:maxLevel=”100″的item放在最前面,那样所有电量都只匹配第一条了。

transition标签

transition其实是继承自layer-list的,只是,transition只能管理两层drawable,另外提供了两层drawable之间切换的方法,切换时还会有淡入淡出的动画效果。示例代码如下:

<?xml version="1.0" encoding="utf-8"?><transition xmlns:andro> <item android:drawable="@drawable/on" /> <item android:drawable="@drawable/off" /></transition>

transition标签生成的Drawable对应的类为TransitionDrawable,要切换时,需要主动调用TransitionDrawable的startTransition()方法,参数为动画的毫秒数,也可以调用reverseTransition()方法逆向切换。

((TransitionDrawable)drawable).startTransition; //正向切换,即从第一个drawable切换到第二个((TransitionDrawable)drawable).reverseTransition; //逆向切换,即从第二个drawable切换回第一个

rotate标签

使用rotate标签可以对一个drawable进行旋转操作,在shape篇讲环形时最后举了个进度条时就用到了rotate标签。另外,比如你有一张箭头向上的图片,但你还需要一个箭头向下的图片,这时就可以使用rotate将向上的箭头旋转变成一张箭头向下的drawable。先看看rotate标签的一些属性吧:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
  • android:fromDegrees 起始的角度度数
  • android:toDegrees 结束的角度度数,正数表示顺时针,负数表示逆时针
  • android:pivotX 旋转中心的X坐标,浮点数或是百分比。浮点数表示相对于drawable的左边缘距离单位为px,如5; 百分比表示相对于drawable的左边缘距离按百分比计算,如5%; 另一种百分比表示相对于父容器的左边缘,如5%p; 一般设置为50%表示在drawable中心
  • android:pivotY 旋转中心的Y坐标
  • android:visible 设置初始的可见性状态,默认为false

示例代码如下,目标是将一张箭头向上的图片转180度,转成一张箭头向下的图片:

<?xml version="1.0" encoding="utf-8"?><rotate xmlns:andro android:drawable="@drawable/ic_arrow" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />

将它引用到ImageView里,发现图片根本没有转变。其实,要让它可以旋转,还需要设置level值。level取值范围为010000,应用到rotate,则与fromDegreestoDegrees相对应,如上面例子的角度范围为0~180,那么,level取值0时,则旋转为0度;level为10000时,则旋转180度;level为5000时,则旋转90度。因为level默认值为0,所以图片没有转变。那么,我们想转180度,其实可以将fromDegrees设为180,而不设置toDegrees,这样,不用再在代码里设置level图片就可以旋转180了。

animation-list标签

通过animation-list可以将一系列drawable构建成帧动画,就是将一个个drawable,一帧一帧的播放。通过添加item子标签设置每一帧使用的drawable资源,以及每一帧持续的时间。示例代码如下:

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:andro android:oneshot="false"> <item android:drawable="@drawable/anim1" android:duration="1000" /> <item android:drawable="@mipmap/anim2" android:duration="1000" /> <item android:drawable="@mipmap/anim3" android:duration="1000" /></animation-list>

注意:1.必须要把 animated-list 设置成主标签2.只有通过 andorid:src 引用才可以,也就是button类的控件不能这样设置动画3.如果控件没有效果,需在代码中这样设置:

 private ImageButton hh; hh = (ImageButton) findViewById(R.id.imageButton); Drawable drawable = hh.getDrawable(); if (!((AnimationDrawable) drawable).isRunning { ((AnimationDrawable) drawable).start(); }
  • android:oneshot属性设置是否循环播放,设为true时,只播放一轮就结束,设为false时,则会轮询播放。
  • android:duration属性设置该帧持续的时间,以毫秒数为单位。
  • animation-list对应的Drawable类为AnimationDrawable,要让动画运行起来,需要主动调用AnimationDrawable的start()方法。另外,如果在Activity的onCreate()方法里直接调用start()方法会没有效果,因为view还没有初始化完成是播放不了动画的。

animated-rotate

rotate标签只是将原有的drawable转个角度变成另一个drawable,它是静态的。而animated-rotate则会让drawable不停地做旋转动画。animated-rotate可设置的属性只有四个:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
  • android:pivotX 旋转中心的X坐标
  • android:pivotY 旋转中心的Y坐标
  • android:visible 设置初始的可见性状态,默认为false
<?xml version="1.0" encoding="utf-8"?><animated-rotate xmlns:andro android:drawable="@drawable/img_daisy" android:pivotX="50%" android:pivotY="50%" android:visible="false" />

注意:1.必须要把 animated-rotate 设置成主标签2.只有通过 andorid:src 引用才可以,也就是button类的控件不能这样设置动画3.如果控件没有效果,需在代码中这样设置:

 private ImageButton hh; hh = (ImageButton) findViewById(R.id.imageButton); Drawable drawable = hh.getDrawable(); if (!((Animatable) drawable).isRunning { ((Animatable) drawable).start(); }

编辑:编程技术 本文来源:Android样式研究

关键词:

  • 上一篇:没有了
  • 下一篇:没有了