Drawable是对可绘制资源的一种抽象,他和view不同,它不具有可交互性。在我们的项目结构中,通常在res下面有一个名为drawable的文件夹,里面的资源我们是可以通过以下两种方式获取:
(1)R.drawable.xxx
(2)getResources().getDrawable(R.drawable.xxx)
接下来我就会对常用的Drawable(本身是一个抽象类)子类的使用做一个简单的介绍,今天主要介绍一下LayerDrawable,在看之前也可以看一下我的上一篇关于BitmapDrawable基本使用的博客
1,LayerDrawable
这个和BitmapDrawable不同,它主要用于管理一组Drawable,官方给出的解释如下:
【
A Drawable that manages an array of other Drawables. These are drawn in array order, so the element with the largest index will be drawn on top.
It can be defined in an XML file with the <layer-list>
element. Each Drawable in the layer is defined in a nested <item>
.
管理一组其他Drawable的Drawable对象,它们会根据索引依次被绘制
我们可以在一个xml文件通过<layer-list>标签来在里面定义元素,每一个Drawable(元素)对应于一个<item>标签
】
构造方法:
LayerDrawable(Drawable[] layers) Create a new layer drawable with the list of specified layers. |
接口方法:
void |
draw(Canvas canvas) Draw in its bounds (set via setBounds) respecting optional effects such as alpha (set via setAlpha) and color filter (set via setColorFilter). |
Drawable |
findDrawableByLayerId(int id) Look for a layer with the given id, and returns its Drawable . |
int |
getChangingConfigurations() Return a mask of the configuration parameters for which this drawable mau change, requiring that it be re-created. |
Drawable.ConstantState |
getConstantState() |
Drawable |
getDrawable(int index) Returns the drawable at the specified layer index. |
int |
getId(int index) Returns the id of the specified layer. |
int |
getIntrinsicHeight() Return the intrinsic height of the underlying drawable object. |
int |
getIntrinsicWidth() Return the intrinsic width of the underlying drawable object. |
int |
getNumberOfLayers() Returns the number of layers contained within this. |
int |
getOpacity() Return the opacity/transparency of this Drawable. |
boolean |
getPadding(Rect padding) Return in padding the insets suggested by this Drawable for placing content inside the drawable's bounds. |
void |
inflate(Resources r, XmlPullParser parser, AttributeSet attrs) |
void |
invalidateDrawable(Drawable who) Called when the drawable needs to be redrawn. |
boolean |
isStateful() Indicates whether this view will change its appearance based on state. |
Drawable |
mutate() Make this drawable mutable. |
void |
scheduleDrawable(Drawable who, Runnable what, long when) A Drawable can call this to schedule the next frame of its animation. |
void |
setAlpha(int alpha) Specify an alpha value for the drawable. 0 means fully transparent, and 255 means fully opaque. |
void |
setColorFilter(ColorFilter cf) Specify an optional colorFilter for the drawable. |
void |
setDither(boolean dither) Set to true to have the drawable dither its colors when drawn to a device with fewer than 8-bits per color component. |
boolean |
setDrawableByLayerId(int id, Drawable drawable) Sets (or replaces) the Drawable for the layer with the given id. |
void |
setId(int index, int id) Sets the ID of a layer. |
void |
setLayerInset(int index, int l, int t, int r, int b) Specify modifiers to the bounds for the drawable[index]. |
boolean |
setVisible(boolean visible, boolean restart) Set whether this Drawable is visible. |
void |
unscheduleDrawable(Drawable who, Runnable what) A Drawable can call this to unschedule an action previously scheduled with Drawable.Callback.scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long) . |
里面有很多和BitmapDrawable同名的方法,几个主要不同的有设置边距(padding),设置可见性以及和子Drawable的ID相关的,其实主要还是体现在一个是Drawable子类,一个是管理Drawable子类(包括它自身)
2,简单使用
第一步:编写LayerDrawable对应的资源xml文件
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<solid android:color="#ffbbbbbb" />
<corners android:radius="2dp" />
</shape>
</item >
<item
android:bottom="10px"
android:right="10px"
android:left="10px"
android:top="10px">
<shape android:shape="rectangle" >
<solid android:color="#ffF0E68C" />
<corners android:radius="10dp" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
</item >
<item
android:drawable="@drawable/face_man"
android:bottom="10px"
android:right="10px"
android:left="10px"
android:top="10px">
</item >
</layer-list>
这个xml文件相较在BitmapDrawable介绍中的要复杂一下,但是结构很清晰,在<layer-list>标签下有三个<item>子标签,第一个是圆角矩形,圆角2dp;第二个首先设置与上一个图层(Drawable)的边距,然后本身也是一个圆角矩形,并且设置了自身内容与自身边框的边距(padding);第三个就简单了,设置了与上一图层的边距和自身的背景图片;
值得注意的是,下一个的
android:bottom="10px"
android:right="10px"
android:left="10px"
android:top="10px"
属性和上一个的
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
效果类似。还有就是我们在官方解释中也知道了最大index会被绘制在最上层,这里很显然index大小和<item>标签顺序保持一致的,index从0开始,我们想获取LayerDrawable里面子Drawable的属性很多都是通过index来定位
第二步:编写测试代码
LayerDrawableActivity:
package com.hfut.operationdrawable;
import android.graphics.drawable.LayerDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
/**
* @author why
* @date 2018-8-13 19:33:26
*/
public class LayerDrawableActivity extends AppCompatActivity {
ImageView imageView;
LayerDrawable layerDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layer_drawable);
imageView=findViewById(R.id.layer_view);
layerDrawable = (LayerDrawable) getResources().getDrawable(R.drawable.layer_drawable);
}
public void decorateImage(View view){
//imageView.setImageDrawable(null);
imageView.setImageDrawable(layerDrawable);
}
public void showNormalImage(View view){
//imageView.setImageDrawable(null);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.face_man));
}
}
activity_layer_drawable.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.hfut.operationdrawable.LayerDrawableActivity">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:id="@+id/layer_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/face_man" />
<LinearLayout
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_marginLeft="20dp"
android:onClick="decorateImage"
android:text="加上边框"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_marginLeft="20dp"
android:onClick="showNormalImage"
android:text="去除边框"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
第三步:测试结果
点击“加上边框”
可见,这个可以用于图片的装饰处理还是不错了。