Drawable以及动画简介

3.5 Drawable以及动画简介

3.5.1 Drawable简介

  1. Drawable表示的是一种可以在Canvas上进行绘制的概念,它的种类很多,最常见的就是图片和颜色了。它有两个重要的优点:一是比自定义view要简单;二是非图片类型的drawable占用空间小。
  2. Drawable的内部宽/高可以通过getIntrinsicWidth和getIntrinsicHeight方法获取,但是并不是所有Drawable都有内部宽/高。图片Drawable的内部宽高就是图片的宽高,但是颜色Drawable就没有宽高的概念,它一般是作为view的背景,所以会去适应view的大小,这两个方法都是返回-1。

3.5.2 Drawable分类

BitmapDrawable和NinePatchDrawable

<?xml version="1.0" encoding="utf-8"?>
<bitmap / nine-patch
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:antialias=["true" | "false"]
    android:dither=["true" | "false"]
    android:filter=["true" | "false"]
    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

属性分析:

  • android:antialias:是否开启图片抗锯齿功能。开启后会让图片变得平滑,同时也会一定程度上降低图片的清晰度,建议开启;
  • android:dither:是否开启抖动效果。当图片的像素配置和手机屏幕像素配置不一致时,开启这个选项可以让高质量的图片在低质量的屏幕上还能保持较好的显示效果,建议开启。
  • android:filter:是否开启过滤效果。当图片尺寸被拉伸或压缩时,开启过滤效果可以保持较好的显示效果,建议开启;
  • android:gravity:当图片小于容器的尺寸时,设置此选项可以对图片进行定位。
  • android:tileMode:平铺模式,有四种选项["disabled" | "clamp" | "repeat" | "mirror"]。当开启平铺模式后,gravity属性会被忽略。repeat是指水平和竖直方向上的平铺效果;mirror是指在水平和竖直方向上的镜面投影效果;clamp是指图片四周的像素会扩展到周围区域,这个比较特别。

ShapeDrawable

<?xml version="1.0" encoding="utf-8"?>
<shape    
    xmlns:android="http://schemas.android.com/apk/res/android"    
    android:shape=["rectangle" | "oval" | "line" | "ring"]>
    <corners        //当shape为rectangle时使用
        android:radius="integer"        //半径值会被后面的单个半径属性覆盖,默认为1dp
        android:topLeftRadius="integer"        
        android:topRightRadius="integer"        
        android:bottomLeftRadius="integer"        
        android:bottomRightRadius="integer" />    
    <gradient       //渐变
        android:angle="integer"        
        android:centerX="integer"        
        android:centerY="integer"        
        android:centerColor="integer"        
        android:endColor="color"        
        android:gradientRadius="integer"        
        android:startColor="color"        
        android:type=["linear" | "radial" | "sweep"]        
        android:useLevel=["true" | "false"] />    
    <padding        //内边距
        android:left="integer"        
        android:top="integer"        
        android:right="integer"        
        android:bottom="integer" />    
    <size           //指定大小,一般用在imageview配合scaleType属性使用
        android:width="integer"        
        android:height="integer" />    
    <solid          //填充颜色
        android:color="color" />    
    <stroke         //边框
        android:width="integer"        
        android:color="color"        
        android:dashWidth="integer"        
        android:dashGap="integer" />
</shape>

android:shape:默认的shape是矩形,line和ring这两种形状需要通过<stroke>来制定线的宽度和颜色,否则看不到效果。
gradient:solid表示纯色填充,而gradient表示渐变效果。android:angle指渐变的角度,默认为0,其值必须是45的倍数,0表示从左到右,90表示从下到上,其他类推。
padding:这个表示的是包含它的view的空白,四个属性分别表示四个方向上的padding值。
size:ShapeDrawable默认情况下是没有宽高的概念的,但是可以如果指定了size,那么这个时候shape就有了所谓的固有宽高,但是作为view的背景时,shape还是会被拉伸或者缩小为view的大小。

LayerDrawable

对应标签<layer-list>,表示层次化的Drawable集合,实现一种叠加后的效果。
属性android:top/left/right/bottom表示drawable相对于view的上下左右的偏移量,单位为像素。

StateListDrawable

对应标签<selector>,也是表示Drawable集合,每个drawable对应着view的一种状态。
一般来说,默认的item都应该放在selector的最后一条并且不附带任何的状态。

LevelListDrawable

对应标签<level-list>,同样是Drawable集合,每个drawable还有一个level值,根据不同的level,LevelListDrawable会切换不同的Drawable,level值范围从0到100000。

TransitionDrawable

对应标签<transition>,它用于是吸纳两个Drawable之间的淡入淡出效果。

<transition xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/shape_drawable_gradient_linear"/>
    <item android:drawable="@drawable/shape_drawable_gradient_radius"/>
</transition>
TransitionDrawable drawable = (TransitionDrawable) v.getBackground();
drawable.startTransition(5000);

InsetDrawable

对应标签<inset>,它可以将其他drawable内嵌到自己当中,并可以在四周留出一定的间距。当一个view希望自己的背景比自己的实际区域小的时候,可以采用InsetDrawable来实现。

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="15dp"
    android:insetLeft="15dp"
    android:insetRight="15dp"
    android:insetTop="15dp" >

    <shape android:shape="rectangle" >
        <solid android:color="#ff0000" />
    </shape>
</inset>

ScaleDrawable

对应标签<scale>,它可以根据自己的level将指定的Drawable缩放到一定比例。如果level越大,那么内部的drawable看起来就越大。

ClipDrawable

对应标签<clip>,它可以根据自己当前的level来裁剪另一个drawable,裁剪方向由android:clipOrientation和andoid:gravity属性来共同控制。level越大,表示裁剪的区域越小。

<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/image1"
    android:gravity="bottom" />

3.5.3 自定义Drawalbe

Drawable的工作核心就是draw方法,所以自定义drawable就是重写draw方法,当然还有setAlpha、setColorFilter和getOpacity这几个方法。当自定义Drawable有固有大小的时候最好重写getIntrinsicWidth和getIntrinsicHeight方法。Drawable的内部大小不等于Drawable的实际区域大小,Drawable的实际区域大小可以通过它的getBounds方法来得到,一般来说它和view的尺寸相同。

3.6.2 view动画

布局动画(LayoutAnimation)属性分析

<layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="0.5"
    android:animationOrder="reverse"
    android:animation="@anim/anim_item"/>

android:delay:表示子元素开始动画的时间延迟,比如子元素入场动画的时间周期是300ms,那么0.5表示每个子元素都需要延迟150ms才能播放入场动画。

给ViewGroup指定LayoutAnimation的两种方式:xml中指定或者Java代码中指定:

//xml
android:layoutAnimation="xxx"
//java
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);

Activity切换效果:在startActivity方法后或者finish方法之后调用overridePendingTransition(int inAnim, int outAnim)方法设置进入或者退出的动画效果。

3.6.3 属性动画

  1. 属性动画可以对任意对象的属性进行动画而不仅仅是view,动画默认的时间间隔是300ms,默认帧率是10ms/帧。
  2. 属性android:repeatMode表示动画的重复模式,repeat表示连续重复播放,reverse表示逆向重复播放,也就是第一次播放完后第二次倒着播放动画,第三次还是重头开始播放动画,第四次再倒着播放,以此类推。
  3. 插值器和估值器:时间插值器(TimeInterpolator)的作用是根据时间流逝的百分比计算出当前属性值改变的百分比,系统内置的插值器有线性插值器(LinearInterpolator)、加速减速插值器(AccelerateDecelerateInterpolator)和减速插值器(DecelerateInterpolator)。类型估值器(TypeEvaluator)的作用是根据当前属性改变的百分比计算出改变后的属性值,系统内置的估值器有IntEvaluator、FloatEvaluator和ArgbEvaluator。
  4. 动画监听器:AnimatorListener:监听动画的开始、结束、取消以及重复播放;AnimatorUpdateListener:监听动画的整个过程,动画每播放一帧的时候onAnimationUpdate方法就会被回调一次。
  5. 对任意属性做动画的方法:封装原始对象或者ValueAnimator。
  6. 属性动画的工作原理:属性动画需要运行在有Looper的线程中,反射调用get/set方法。

3.6.4 使用动画的注意事项

  1. 内存泄露:属性动画中的无限循环动画需要在Activity退出的时候及时停止,否则将导致Activity无法释放而造成内存泄露,view动画不存在这个问题。
  2. view动画:view动画是对view的影像做动画,并不是真正的改变view的状态,因此有时候动画完成之后view无法隐藏,即setVisibility(View.GONE)失效了,此时需要调用view.clearAnimation()清除view动画才行。
  3. 动画元素的交互:在android3.0以前上,view动画和属性动画,新位置均无法触发点击事件,同时,老位置仍然可以触发单击事件。从3.0开始,属性动画的单击事件触发位置为移动后的位置,view动画仍然在原位置。
  4. AnimationSet的属性android:shareInterpolator表示集合中的动画是否共享同一个插值器,如果集合不指定插值器,那么子动画需要单独指定所需的插值器或者使用默认值。
  5. 自定义动画需要继承Animation抽象类,并重新它的initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation方法中进行相应的矩阵变换,很多时候需要采用Camera类来简化矩阵变换的过程。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容