Drawable入门
来源:互联网 发布:逆战淘宝代练1元一把 编辑:程序博客网 时间:2024/06/05 22:33
Drawable
一个drawable就是一个图形资源。使用起来就和使用一个具体的图片一样。但是也有几种特殊的。
常用方法
setBounds():设置一个矩形区域,当Drawable.draw()被调用时该drawable便会被画到指定的区域中。
BitmapDrawable
一张图片。
xml
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@mipmap/bg" android:tileMode="repeat" />
以bitmap为根结点,由src属性指定对应的图片资源。常用属性如下:
tileMode:src的重复模式。repeat图片在x,y轴方向上不断重复;mirror图片在x,y轴上以镜像排列;clamp用图片的最外缘一圈像素填充剩余的地方。因此对于下面形式的图片,只要截取一个基本重复单元,将tileMode设置为repeat就可以实现。图片如下:
alpha:图片的透明度。0完全透明
antialias:图片是否搞锯齿
dither:图片是否防抖动——不明白这个抖动是啥玩意,不过建议开启
filter:图片是否过滤——不知道开启与不开启有啥区别,不过建议开启
gravity:当图片尺寸小于显示的View的尺寸时,用于定位图片的显示位置。与常用的gravity属性差不多。
mipMap:不懂,就按默认的设置为false即可。
BitmapDrawable
<bitmap>对应的java类为BitmapDrawable。大部分方法都是由上面的属性想对应的,其余的常用方法为:
setColorFilter():与Paint#setColorFilter()方法的作用是一样的。
NinePatchDrawable
与BitmapDrawable类似,它代表了一个.9图片。
xml属性:以nine-patch为根结点,其余属性与BitmapDrawable一样,只不过src需要一个.9的图片。如下:
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/bg" android:tileMode="repeat" />
其中的tileMode无效。
ScaleDrawable
对应<scale>标签,将指定的drawable进行缩放。常用属性
scaleGravity:与gravity类似,缩放后的drawable显示的位置。
scaleWidth与scaleHeight:宽、高上的缩放比例。
使用scaleDrawable有一点要注意:必须调用ScaleDrawable#setLevel(),并传入大于1的参数。原因如下:
@Override public void draw(Canvas canvas) {//ScaleDrawable的draw() final Drawable d = getDrawable(); if (d != null && d.getLevel() != 0) { d.draw(canvas); } }从draw()方法中可以看出,如果level==0的话,是不会进行绘制的,也就是不显示任何内容。而level默认的就是0,所以必须调用setLevel为level进行重新赋值。
xml示例如下:
<scale android:drawable="@mipmap/fengjing" android:scaleGravity="center_horizontal" android:scaleHeight="90%" android:scaleWidth="20%" xmlns:android="http://schemas.android.com/apk/res/android" />对应的代码为:
ImageView iv = (ImageView) findViewById(R.id.image); ScaleDrawable drawabl1e = (ScaleDrawable) iv.getDrawable(); drawabl1e.setLevel(1);
TransitionDrawable
基础
可以在两个drawable之间形成淡入淡出(cross-fade)效果。如同写布局一样,它的定义方式有两种:在xml文件中和通过代码生成(即使用TransitionDrawable类)。
要注意的是:无论是通过xml还是代码,都必须调用TransitionDrawable.startTransition()才能有效果。
xml中
在res/drawable目录下,建立一个xml。xml具体如下:
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </transition>其中根结点必须是transition。每一个<item>就代表着一个要加入到TransitionDrawable中的drawable。示例:
<?xml version="1.0" encoding="utf-8"?><transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/on" /> <item android:drawable="@drawable/off" /></transition>
相应的代码
ImageView iv = (ImageView) findViewById(R.id.listView1);iv.setImageResource(R.drawable.t_drawable);//也可以直接在xml中设置final TransitionDrawable drawable = (TransitionDrawable) iv.getDrawable();//获取相应的drawabledrawable.startTransition(1500);//开始new Handler().postDelayed(new Runnable() {public void run() {drawable.reverseTransition(4000);}}, 2000);
通过代码生成
示例如下:
Drawable[] layers = new Drawable[2];//定义图片资源layers[0] = getResources().getDrawable(R.drawable.chatto_bg_voiceforward_focused);layers[1] = getResources().getDrawable(R.drawable.friendactivity_remind_normal);final TransitionDrawable drawable = new TransitionDrawable(layers);//生成相应的drawableImageView iv = (ImageView) findViewById(R.id.listView1);iv.setImageDrawable(drawable);//设置到对应的imageview中drawable.startTransition(1500);//开始new Handler().postDelayed(new Runnable() {public void run() {drawable.reverseTransition(4000);}}, 2000);
方法
startTransition(int durationMillis):开始执行淡入淡出的动画,此时第一张淡出,第二张淡入。
reverseTransition(int duration):从当前状态往回显示。开始时第一张淡入,第二张淡出。但如果执行该方法时第一张已经完全显示,就类似startTransition(),第一张淡出,第二张淡入。
LayerDrawable
理解
它控制着一系列的drawable,里面的drawable是按层分布的,类似于Framelayout。最后的一个drawable出现在最上面。最常见的例子便是ProgressBar(分了三层)。
xml中
在res/drawable目录下,建立一个xml。xml具体格式同上面类似,只不过把根结点为<layer-list>。示例:
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item> <bitmap android:gravity="center" android:src="@drawable/red" /> </item> <item android:left="10dp" android:top="10dp"> <bitmap android:gravity="center" android:src="@drawable/blue" /> </item> <item android:left="20dp" android:top="20dp"> <bitmap android:gravity="center" android:src="@drawable/green" /> </item></layer-list>
其中的top,left,bottom,right等属性表示Drawable相对于整个View的偏移量。
在上面,并没有直接在<item>中通过drawable引用相应的图片,这是因为直接引用时,这些图片会被缩放去适应整个容器。为避免这个情况才在<item>下使用了<bitmap>。效果图如下:
其中上面一张是没有使用<bitmap>结点的,下面一张是使用<bitmap>结点的。
LevelListDrawable
xml对应的是<level-list>根结点。其类似于LayerDrawable,但LayerDrawable会将所有的Drawable分层,显示时会全部显示。但LevelListDrawable只会根据当前指定的level显示出指定level上的图片。某一drawable所处的level,可以通过maxLevel和minLevel指定一个范围。如下:
<level-list xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <item android:drawable="@mipmap/baidu" android:maxLevel="10" android:minLevel="8" /> <item android:drawable="@mipmap/fengjing" android:maxLevel="6" android:minLevel="2" /></level-list>对应的java代码为:
ImageView iv = (ImageView) findViewById(R.id.image); iv.setImageLevel(5);//通过该方法指定当前ImageView要显示的层 ImageView imageView = (ImageView) findViewById(R.id.image2); LevelListDrawable drawable = new LevelListDrawable(); drawable.addLevel(2,6, ContextCompat.getDrawable(this,R.mipmap.fengjing)); drawable.addLevel(8,10, ContextCompat.getDrawable(this,R.mipmap.baidu)); imageView.setImageDrawable(drawable); imageView.setImageLevel(9);效果图为
上面的是通过xml文件加载的,下面的是通过代码指定的。从中可以看出,并没有显示所有的drawable,只是根据level层,显示了当前层指定的drawable。
StateListDrawable
状态选择器,根结点就是selector。当状态改变时,一系列的图片会重新遍历一遍,只要有一个满足当前状态的,就会停止遍历,并采用当前的图片。但是,这个满足当前状态的并不一定是最合适的。也就是说它只求满足,并不求最适合。
参考:http://blog.csdn.net/leasystu/article/details/7250885
状态说明:
android:state_selected
:被选中。有可能是通过方向键进行选中的,并不一定具有焦点。
android:state_checkable
:是否可选。
android:state_checked
:是否选中。
android:state_enabled
:是否可用。
android:state_window_focused
:当前窗口是否具有焦点。如:notification被拉下来或者dialog显示的时候,该窗口就没有焦点。
ShapeDrawable
对应res/drawable的shape标签。有一点要注意:该drawable必须设置bounds,如果不设置便不会绘制内部的shape。
它能绘制一些原始的简单的图形,一个ShapeObject内部含有一个Shape对象(默认是RectShape),并且控制着Shape在屏幕上的显示。如
//一个黄色宽度为2的圆环public class CustomShapeDrawable extends View { private ShapeDrawable drawable; public CustomShapeDrawable(Context context) { this(context, null); } public CustomShapeDrawable(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomShapeDrawable(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { int x = 10, y = 10; drawable = new ShapeDrawable(new OvalShape());//Oval为椭圆形 Paint paint = drawable.getPaint();//通过获取的paint可以设置绘画的形状 paint.setColor(Color.YELLOW); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); drawable.setBounds(x, y, x + 100, y + 100);//设置shape绘制的位置 } @Override protected void onDraw(Canvas canvas) { drawable.draw(canvas);//调用drawable的draw方法进行绘制 }}
ClipDrawable
clip_test.xml
<clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal" android:drawable="@drawable/fengjing1114" android:gravity="left" ></clip>对应的activity中的代码:
//该imageview已经设置了android:src="@drawable/clip_test"ImageView iv = (ImageView) findViewById(R.id.iv);clipDrawable = (ClipDrawable) iv.getDrawable();final Timer timer = new Timer();timer.schedule(new TimerTask() {public void run() {if (mLevel >= 10000) {timer.cancel();return;}mLevel += 201;mLevel = Math.min(mLevel, 10000);System.out.println("mlevel = " + mLevel);runOnUiThread(new Runnable() {public void run() {clipDrawable.setLevel(mLevel);}});}}, 0, 100);
InsetDrawable
将一个drawable嵌入到另一张drawable中,根结点是inset。在嵌入的过程中,可以设置内部drawable与外围drawable之前的距离。具体示例如下,其中insetXXX属性就是设置距离的,并且这些属性还可以设置成负数,此时图片就会自动地将负数对应的部分给截掉。<?xml version="1.0" encoding="utf-8"?><inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/fengjing1114" android:insetBottom="6dp" android:insetLeft="3dp" android:insetRight="5dp" android:insetTop="4dp" ></inset>效果为:
应用
阴影效果
结合layer-list与InsetDrawable可以仿造成阴影效果。主要思路是:通过InsetDrawable构建一个留有边框的drawable,再在该drawable底层放一个渐变的drawable即可。为实现在底层放一个drawable,就需要用layer-list。效果图为:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 在底部画一个渐变的drawable,充当背景 --> <item> <shape android:shape="rectangle" > <corners android:radius="4dp" /> <gradient android:angle="90" android:centerColor="#ee000000" android:centerY="0.05" android:endColor="#000000" android:startColor="#00000000" /> </shape> </item> <!-- 这个item才是要显示的drawable --> <item> <inset android:drawable="@drawable/shape_bg" android:insetBottom="5dp" /> </item></layer-list>直接在布局中引用该drawable即可。这样做只能实现单边的阴影效果,如果想要多边的,直接用图片吧。
- Drawable入门
- Android入门/Drawable(十七)
- 帧动画Drawable Animation入门
- Drawable
- Drawable
- Drawable
- Drawable
- drawable
- Drawable
- Drawable
- Drawable
- Drawable
- Drawable
- android.graphics.drawable.Drawable
- android drawable Transition Drawable
- Drawable之Shape drawable
- Android 2.1 android.R.drawable Icon Resources Android 2.2 快速入门
- Android入门——Drawable与对应的资源xml的应用
- [Struts2] No result defined for action ... and result input & Invalid field value for field ...
- nor flash 和nand flash 傻傻分不清楚
- iTween插件
- 字符串__常用字符串函数
- 遗传算法
- Drawable入门
- 如何把VS2008上编的debug、release程序在没装VS的xp机器上运行
- easyui-tabs根据数据库的数据动态生产tab
- Android Launcher分析和修改1——Launcher默认界面配置(default_workspace)
- Qt for Android 配置详细 (linux下的)
- jqMobi插件(2)--JSON格式的ActionSheet
- 读“企鹅物联,靠谱吗?”有感
- 第十一周项目 5 当年第几天
- history.go(-1)在不同浏览器中的解析