Getting started with Android -- Application of Drawable and corresponding resource xml
Introduction
Drawable in Android is an abstract concept. In other words, all drawn items can be defined as Drawable (A Drawable is a general drawing action for "something that can be drawn ."). Therefore, Android applications use the most extensive and flexible resources, not just directly.. Png,.9.png,. Gif,Images such as. jpg can be used as resources and multiple XML files can be used.
1. Drawable Overview
Drawable is also an abstract class. We do not use it directly in Android development. It is often used as a derived class. Common Derived classes include:BitmapDrawable,ClipDrawable,ColorDrawable,DrawableContainer,GradientDrawable,InsetDrawable,LayerDrawable,NinePatchDrawable,PictureDrawable,RotateDrawable,ScaleDrawable,ShapeDrawable,AnimationDrawable,LevelListDrawable,PaintDrawable,StateListDrawable,TransitionDrawable. In the program, we can get the corresponding Drawable object through getDrawable (int id, int theme) of the Resource class.
Ii. Applications of the Drawable system 1. StateListDrawable (selector xml file)
We all know about selector xml files, but StateListDrawable I believe that a considerable number of people may not know about it.StateListDrawableIt can be used to organize multiple Drawable objects. It is often used for the background and foreground of a view. When the view state changes, it will automatically switch.
1.1. xml file structure of the StateListDrawable object
The corresponding root element is selector and can contain multiple item elements.
Android: color or android: drawable: Specifies the color or Drawable object adnroid: state_xxx: a specific status.
Status Attribute Value |
Description |
Android: state_active |
Active or not |
Android: state_checkable |
Check whether |
Android: state_checked |
Checked? |
Android: state_enabled |
Available or not |
Android: state_first |
Start status? |
Android: state_focused |
Whether the focus is obtained |
Android: state_last |
End or not |
Android: state_middle |
In the middle? |
Android: state_pressed |
Whether it is in the pressed status. |
Android: state_selected |
Selected or not |
Android: state_window_focused |
Whether the window has received focus |
Example: selector_mybutton.xml
<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%20%3F%2D%2D%3E--> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--{cke_protected}{C}%3C!%2D%2D%20%E9%BB%98%E8%AE%A4%E6%97%B6%E7%9A%84%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87%2D%2D%3E--> <item android:drawable="@drawable/pic1"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%B2%A1%E6%9C%89%E7%84%A6%E7%82%B9%E6%97%B6%E7%9A%84%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87%20%2D%2D%3E--> <item android:state_window_focused="false" android:drawable="@drawable/pic_nofocus"> <!--{cke_protected}{C}%3C!%2D%2D%20%E9%9D%9E%E8%A7%A6%E6%91%B8%E6%A8%A1%E5%BC%8F%E4%B8%8B%E8%8E%B7%E5%BE%97%E7%84%A6%E7%82%B9%E5%B9%B6%E5%8D%95%E5%87%BB%E6%97%B6%E7%9A%84%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87%20%2D%2D%3E--> <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/pic_click"> <!--{cke_protected}{C}%3C!%2D%2D%20%E8%A7%A6%E6%91%B8%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%8D%95%E5%87%BB%E6%97%B6%E7%9A%84%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87%2D%2D%3E--> <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/pic_touch"> <!--{cke_protected}{C}%3C!%2D%2D%E9%80%89%E4%B8%AD%E6%97%B6%E7%9A%84%E5%9B%BE%E7%89%87%E8%83%8C%E6%99%AF%2D%2D%3E--> <item android:state_selected="true" android:drawable="@drawable/pic_select"> <!--{cke_protected}{C}%3C!%2D%2D%E8%8E%B7%E5%BE%97%E7%84%A6%E7%82%B9%E6%97%B6%E7%9A%84%E5%9B%BE%E7%89%87%E8%83%8C%E6%99%AF%2D%2D%3E--> <item android:state_focused="true" android:drawable="@drawable/pic_getfocus"> </item></item></item></item></item></item></selector></code>
2. LayerDrawable (layer-list xml file)
Similar to StateListDrawable, LayerDrawable can also contain a Drawable array. The system will draw the Drawable objects in the array order, and the largest Drawable index will be drawn at the top.
2.1. xml file structure of the LayerDrawable object
Its root node is layer-list. It can also contain multiple item elements:
Android: drawable: Specifies the id adnroid: buttom | top | left | button: used to specify a length value of the Drawable object android: Id: Drawable to be included, specify that the Drawable object is drawn to the specified position of the target component. 2.2. Implement LayerDrawable in xml
<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!--{cke_protected}{C}%3C!%2D%2D%E6%9C%80%E5%BA%95%E5%B1%82%2D%2D%3E--> <item> <bitmap android:src="@mipmap/ic_blue_launcher" android:gravity="center"> </bitmap></item> <!--{cke_protected}{C}%3C!%2D%2D%E6%AC%A1%E4%B8%8A%E5%B1%82%2D%2D%3E--> <item android:top="10dp" android:left="10dp"> <bitmap android:src="@mipmap/ic_red_launcher" android:gravity="center"> </bitmap></item> <!--{cke_protected}{C}%3C!%2D%2D%E6%98%BE%E7%A4%BA%E5%9C%A8%E6%9C%80%E4%B8%8A%E9%9D%A2%2D%2D%3E--> <item android:top="20dp" android:left="20dp"> <bitmap android:src="@mipmap/ic_green_launcher" android:gravity="center"> </bitmap></item></layer-list></code>
2.3 dynamic generation and use in Java code
Resources resources = getResources (); Drawable [] layers = new Drawable [3]; layers [0] = r. getDrawable (R. drawable. ic_blue_launcher); layers [1] = r. getDrawable (R. drawable. ic_red_launcher); layers [2] = r. getDrawable (R. drawable. ic_green_launcher); LayerDrawable layerDrawable = new LayerDrawable (layers) (ImageView) findViewById (R. id. imageview )). setImageDrawable (layerDrawable);/* Reference in java code: */(ImageView) findViewById (R. id. imageview )). setImageDrawable (getResources (). getDrawable (R. drawable. layer_bcg)
2.4 use layer-list in xml
2.5 simple image synthesis using LayerDrawable
In the Android platform, Bitmap can be painted layer by layer through Canvas. What about the superposition of Drawable? In addition to converting Drawable to Bitmap Using the getBitmap method of BitmapDrawable, there is another solution-LayerDrawable.
Bitmap bm = BitmapFactory. decodeResource (getResources (), R. drawable. ic_red_launcher); Drawable [] array = new Drawable [3]; array [0] = new PaintDrawable (Color. BLACK); // BLACK array [1] = new PaintDrawable (Color. WHITE); // WHITE array [2] = new BitmapDrawable (bm); // bitmap resource LayerDrawable ld = new LayerDrawable (array); // The parameter is the above Drawable array ld. setLayerInset (1, 1, 1, 1, 1); // The first parameter 1 represents the second element of the array, which is white ld. setLayerInset (2, 2, 2, 2, 2); // The first parameter 2 represents the third element of the array, which is the bitmap resource mImageView. setImageDrawable (ld );
As shown in the code above, the prototype of the setLayerInset method is public void setLayerInset (int index, int l, int t, int r, int B). The first parameter is the layer index number, the following four parameters are left, top, right, and bottom. For simple image synthesis, we can replace PaintDrawable on the first and second layers with BitmapDrawable to implement simple image synthesis.
3. ShapeDrawable (shape xml)
ShapeDrawable is used to define basic geometric shapes (such as rectangles, circles, and lines). Its root node isShape(Android: shape = ["rectangle" | "oval" | "line" | "ring"] can be specified in shape to specify the set type .)Corners,Gradient,Padding,Size,Solid,StrokeAnd other sub-nodes.
3.1. Implement ShapeDrawable in an xml file
3.2. Use shape in xml
3.3 construct ShapwDrawable in the code
Constructing a ShapeDrawable object in the Code involves the Shape series.
MImg = (ImageView) findViewById (R. id. demo_img); float [] outerRadii = {20, 20, 40, 40, 60, 60, 80, 80 }; // radius of the upper left, upper right, lower right, and lower left corner of the outer rectangle // float [] outerRadii = {20, 20, 20, 20, 20, 20, 20 }; // RectF inset = new RectF (100,100,200,200) radius of the top left, top right, bottom right, and bottom left corner of the outer rectangle; // The distance between the inner rectangle and the outer rectangle, the distance between the upper left corner x and the y corner, and the bottom right corner x, y distance float [] innerRadii = {20, 20, 20, 20, 20, 20, 20}; // RoundRectShape roundRectShape RoundRectShape = new RoundRectShape (outerRadii, inset, innerRadii); // RoundRectShape roundRectShape = new RoundRectShape (outerRadii, null, innerRadii); // No inner rectangle ShapeDrawable drawable = new ShapeDrawable (vertex); drawable. getPaint (). setColor (Color. GREEN); drawable. getPaint (). setAntiAlias (true); drawable. getPaint (). setStyle (Paint. style. STROKE); // STROKE drawable. getPaint (). setStrokeWidth (20); drawable. setIntrinsicWidth (200); drawable. setIntrinsicHeight (400); drawable. setPadding (new Rect (4, 4, 4, 4); // drawable. setShape (Shape s); mImg. setBackground (drawable );
4. ClipDrawable (clip xml)
ClipDrawable is used to extract an "image fragment" from other bitmaps. The root node is clip, and there are no other subnodes. clip has several attribute nodes:
Android: drawable: Specifies the source Drawable android: clipOrientation: Specifies the direction of the interception, horizontal or vertical interception android: gravity: Specifies the alignment when the Interception
ClipDrawable has an important method: setLevel (int level) can be used to set the size of the area to be intercepted. When level is 0, the area to be intercepted is blank. If it is 10000, the entire image is captured.
4.1 ClipDrawable: a simple application
The effect of the example is to simulate the effect of slowly expanding the image from the center to the left and right sides (if you are too lazy to achieve the auto-expanding effect, you will use a button and click to expand One point at a time)
MImg = (ImageView) findViewById (R. id. demo_img); // obtain the ClipDrawable object final ClipDrawable clipDrawable = (ClipDrawable) mImg displayed in the image. getDrawable (); final Handler handler = new Handler () {@ Override public void handleMessage (Message msg) {if (msg. what = 123) {// modify ClipDrawable's level value clipDrawable. setLevel (clipDrawable. getLevel () + 300) ;}}; Timer timer = new Timer (); timer. schedule (new StartTask (handler, clipDrawable, timer), 2000); Button btn = (Button) findViewById (R. id. plus_level); btn. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {handler. sendEmptyMessage (123 );}});
class StartTask extends TimerTask { private Handler handler; private Drawable drawable; private Timer timer; public StartTask(Handler handler, Drawable drawable, Timer timer) { super(); this.handler = handler; this.drawable = drawable; this.timer = timer; } @Override public void run() { Message msg = new Message(); msg.what = 123; handler.sendMessage(msg); if (drawable.getLevel() >= 10000) { timer.cancel(); } } }
5. AnimationDrawable
AnimationDrawable is believed to be familiar to everyone. In Android, AnimationDrawable supports two types of animations: Frame-by-Frame and Tween ).
5.1 frame-by-frame animation (animation-list xml)
The root node is animation-list, the child node is item, and each item is a frame
Create an AnimationDrawable object in the Code, set it to the background of the view, and set it to start playing:
AnimationDrawable ad = (AnimationDrawable)getResources().getDrawable(R.drawable.bootanimation);mView.setBackgroundDrawable(ad);ad.start();
5.2. set)
The supplementary animation isSetAs the root node, four sub-nodes can be defined in set:
Alpha: sets the transparency of the image (0-1.0) scale: sets the image size to change translate: sets the Image Displacement to change rotate: sets the image rotation to 5.2.1, defines the xml syntax of the compensation Animation
...
5.2.2. Use a complementary animation in the code
ImageView img = (ImageView) findViewById(R.id.tween_bcg);Animation tweenAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_tween);img.startAnimation(tweenAnimation);
6. GradientDrawable
GradientDrawable is the gradient Drawable system, which is illustrated in an example.
package com.crazymo.drawableapp;public class GradientActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Path mPath; private Paint mPaint; private Rect mRect; private GradientDrawable mDrawable; public SampleView(Context context) { super(context); setFocusable(true); mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRect = new Rect(0, 0, 120, 120); mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR, new int[]{0xFFFF0000, 0xFF00FF00, 0xFF0000FF}); mDrawable.setShape(GradientDrawable.RECTANGLE); mDrawable.setGradientRadius((float) (Math.sqrt(2) * 60)); } static void setCornerRadii(GradientDrawable drawable, float r0, float r1, float r2, float r3) { drawable.setCornerRadii(new float[]{r0, r0, r1, r1, r2, r2, r3, r3}); } @Override protected void onDraw(Canvas canvas) { mDrawable.setBounds(mRect); float r = 16; canvas.save(); canvas.translate(10, 10); mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); setCornerRadii(mDrawable, r, r, 0, 0); mDrawable.draw(canvas); canvas.restore(); /*canvas.save(); canvas.translate(10 + mRect.width() + 10, 10); mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT); setCornerRadii(mDrawable, 0, 0, r, r); mDrawable.draw(canvas); canvas.restore(); canvas.translate(0, mRect.height() + 10); canvas.save(); canvas.translate(10, 10); mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT); setCornerRadii(mDrawable, 0, r, r, 0); mDrawable.draw(canvas); canvas.restore(); canvas.save(); canvas.translate(10 + mRect.width() + 10, 10); mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); setCornerRadii(mDrawable, r, 0, 0, r); mDrawable.draw(canvas); canvas.restore(); canvas.translate(0, mRect.height() + 10); canvas.save(); canvas.translate(10, 10); mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT); setCornerRadii(mDrawable, r, 0, r, 0); mDrawable.draw(canvas); canvas.restore(); canvas.save(); canvas.translate(10 + mRect.width() + 10, 10); mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT); setCornerRadii(mDrawable, 0, r, 0, r); mDrawable.draw(canvas); canvas.restore();*/ } }}