1. An overview of the

In practice, in addition to the well-known use of StateListDrawable for button click effects, we sometimes receive requests for our avatars to appear as circular or rounded rectangles, or even with variable color borders, Or ask you to make a set of start, pause, fast-forward and rewind video controls and change the color of their ICONS. There may be times when the first thing to do is to use a custom View, but once you’re familiar with Drawable, these effects can also be done with it.

The official Google documentation lists all kinds of Drawables, but how are they used?

This two-part article series will cover the use of most of them.

2. BitmapDrawable

BitmapDrawable can be regarded as a wrapper around a Bitmap. It can set the display mode, location and other attributes of the Bitmap.

2.1 grammar

BitmapDrawable corresponds to the

tag definition. The XML syntax is as follows:

<?xml version="1.0" encoding="utf-8"? >
<bitmap
    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:mipMap=["true"|"false"]
    android:tileMode=["disabled"|"clamp"|"repeat"|"mirror"/ >
Copy the code

The meanings of each attribute are as follows:

attribute meaning
src The reference path of a Bitmap object
antialias Anti-aliasing effect, you are advised to enable it
dither Whether to prevent jitter. When bitmap pixels do not match screen pixels (for example, ARGB_8888’s bitmap is displayed on RGB_565’s screen), it is recommended to enable this function to prevent image distortion
filter Whether to enable bitmap filtering. When turned on, images can be stretched or compressed for a smooth transition
gravity Position in a container when the bitmap size is smaller than the container size
mipMap Enable or disable mipMap prompt. Default is false
tileMode Tile mode. Default: disable; Clamp: duplicates the color of the edge; Repeat: draw the picture horizontally and vertically; Mirror: Alternating horizontal and vertical mirrors are repeatedly drawn

2.2 Usage Examples

Here is a simple and practical way to define a BitmapDrawable that uses an image as its background.

define

<?xml version="1.0" encoding="utf-8"? >
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@mipmap/kakarotto"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:tileMode="repeat"/>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@drawable/bitmap_drawable"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

rendering

3. The ShapeDrawable and GradientDrawable

ShapeDrawable is defined in the official documentation as follows:

A Drawable object that draws primitive shapes. A ShapeDrawable takes a Shape object and manages its presence on the screen. If no Shape is given, then the ShapeDrawable will default to a RectShape.

This object can be defined in an XML file with the <shape> element.

That is, it is a Drawable object used to draw the original shape.

The definition for GradientDrawable is:

A Drawable with a color gradient for buttons, backgrounds, etc.

It can be defined in an XML file with the <shape> element. For more information, see the guide to Drawable Resources.

According to the description, it is a Drawable with color gradient.

3.1 grammar

GradientDrawable and ShapeDrawable both GradientDrawable and ShapeDrawable use the shape tag. The biggest difference between ShapeDrawable and GradientDrawable is that it has the gradient attribute. The syntax for shape is as follows:

<?xml version="1.0" encoding="utf-8"? >
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape=["rectangle"|"oval"|"line"|"ring"] >
    <corners
        android:radius="integer"
        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:usesLevel=["true"|"false"/ >
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <size
        android:width="integer"
        android:height="integer" />
    <solid
        android:color="color" />
    <stroke
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />
</shape>
Copy the code

The meanings of each attribute tag are as follows:

android:shape

Represents shapes. Its values can be Rectangle, oval, line, or ring. The default is Rectangle. In addition, there are several properties that can be configured when the shape value is ring:

attribute meaning
android:innerRadius The inner radius of the ring. When set together with innerRadiusRatio, the innerRadiusRatio prevails
android:innerRadiusRatio The ratio of the inner radius of a ring to the width of the ring
android:thickness Ring thickness. If both thicknessRatio and thicknessRatio are set at the same time, thicknessRatio shall prevail
android:thicknessRatio The ratio of the thickness of a ring to its width
android:useLevel It is generally false, otherwise it may not display as expected unless it is used as LevelListDrawable

<corners>

<corners
    android:radius="integer"
    android:topLeftRadius="integer"
    android:topRightRadius="integer"
    android:bottomLeftRadius="integer"
    android:bottomRightRadius="integer" />
Copy the code

Rectangle radius refers to the radius of a rectangle, which is only effective when Rectangle is set to Shape. The smaller the value, the closer it is to a right Angle. Android :radius sets the radius of four corners, and the other four attributes set the radius of a corner separately.

<gradient>

<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:usesLevel=["true"|"false"/ >
Copy the code

Represents the color gradient, and the meanings of its attribute values are as follows:

attribute meaning
android:angle Gradient Angle. The value must be a multiple of 45. The default value is 0. 0 is left to right, 90 is top to bottom
android:centerX The relative X-axis position of the gradient center (0-1.0)
android:centerY The relative Y-axis position of the gradient center (0-1.0)
android:startColor The initial color of the gradient
android:centerColor Gradient middle color
android:endColor End color of gradient
android:gradientRadius The radius of the gradient,Only in theandroid:type="radial"When applicable
android:useLevel It is generally false, otherwise it may not display as expected unless it is used as LevelListDrawable
android:type Gradient categories. Its values can be linear, default, radial, and sweep.

<padding>

The inner margin from the content or child element, each direction can be set separately.

<size>

Set the shape size, width for width and height for height. Note that this is generally not the final size of the Shape. If used as the background of a View, its size is determined by the size of the View.

<solid>

Represents a solid color fill. The color property is the color of the fill.

<stroke>

Border description, and the meanings of each attribute value are as follows:

attribute meaning
android:width Border width
android:color Border color
android:dashWidth The width of the dashed line segment
android:dashGap The space between the dotted lines

Note that if you want to set the border dash effect, you must set the dashWidth and dashGap values not to 0 at the same time; otherwise, the dash effect cannot be displayed.

3.2 Usage Examples

Here’s a simple example of a GradientDrawable that defines a rounded Drawable with other effects.

define

<?xml version="1.0" encoding="utf-8"? >
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">

    <! -- Fillet radius -->
    <corners
            android:topLeftRadius="15dp"
            android:topRightRadius="15dp"
            android:bottomLeftRadius="15dp"
            android:bottomRightRadius="15dp"/>

    <! -- Inner margin -->
    <padding
            android:left="10dp"
            android:top="10dp"
            android:right="10dp"
            android:bottom="10dp" />

    <! -- Gradient Effect -->
    <gradient android:angle="45"
              android:type="linear"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff" />

    <! -- Default size -->
    <size
        android:width="200dp"
        android:height="100dp" />

    <! -- Border Style -->
    <stroke
            android:width="2dp"
            android:color="# 000000"
            android:dashWidth="7dp"
            android:dashGap="3dp" />

</shape>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".GradientDrawableActivity">

    <Button
            android:text="Button"
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="@drawable/gradient_drawable"
            android:id="@+id/textView"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

rendering

4. StateListDrawable

StateListDrawable can use different Item (Drawable) objects to represent the same graph depending on the state of the object. For example, different Drawable can be displayed according to the state of the Button (press down, get focus, etc.) to achieve the effect of clicking.

4.1 grammar

The syntax for defining StateListDrawable is as follows:

<?xml version="1.0" encoding="utf-8"? >
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize=["true"|"false"]
    android:dither=["true"|"false"]
    android:variablePadding=["true"|"false"] 
    android:autoMirrored=["true"|"false"] 
    android:enterFadeDuration="integer"
    android:exitFadeDuration="integer">
    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:state_pressed=["true"|"false"]
        android:state_focused=["true"|"false"]
        android:state_hovered=["true"|"false"]
        android:state_selected=["true"|"false"]
        android:state_checkable=["true"|"false"]
        android:state_checked=["true"|"false"]
        android:state_enabled=["true"|"false"]
        android:state_activated=["true"|"false"]
        android:state_window_focused=["true"|"false"/ >
</selector>
Copy the code

The root tag of StateListDrawable is **<selector>, and the meaning of each attribute tag is:

android:constantSize

Since StateListDrawable displays different Drawable values depending on the state, each Drawable may not be the same size. Therefore, the constantSize attribute is true for a fixed size (the maximum inherent size of all Drawable), and false for the size of the corresponding Drawable in its current state. The default value is false.

android:variablePadding

The padding value indicates whether the StateListDrawable changes with the state. Default is false.

android:dither

Whether to enable jitter. The default value is true. You are advised to enable jitter.

android:autoMirrored

In some West Asian countries, text is from right to left. Setting this value indicates whether the image is mirrored when the system is configured with right-to-left (RTL) layout.

Android: enterFadeDuration and android: exitFadeDuration

Duration of fade-in effect when state changes

<item>

Each item represents a Drawable, and the attributes of item are as follows:

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
android:state_pressed Whether it is in the pressed state
android:state_focused Whether the focus state has been obtained
android:state_hovered The state in which the cursor stays within the View’s own size
android:state_selected Whether the server is in the selected state
android:state_checkable Whether it is available
android:state_checked Whether it is selected
android:state_enabled Whether it is in the available state
android:state_active Whether the state is active
android:state_window_focused Whether the window is in focus state

4.2 Usage Examples

The following example shows the use of StateListDrawable by customizing a Button background with the click effect.

define

<?xml version="1.0" encoding="utf-8"? >
<selector
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:visible="true"
        android:dither="true"
        android:autoMirrored="true"
        android:enterFadeDuration="200"
        android:exitFadeDuration="200" >
    <! Get focus state -->
    <item
            android:state_focused="true"
            android:drawable="@drawable/shape_dark" />

    <! -- Press down state -->
    <item
            android:state_pressed="true"
            android:drawable="@drawable/shape_dark"/>

    <! -- Default state -->
    <item
            android:drawable="@drawable/shape_light"/>
</selector>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@android:color/holo_orange_dark"
    tools:context=".LayerDrawableActivity">

    <Button
            android:text="Button"
            android:background="@drawable/drawable_state_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

rendering

5. LayerDrawable

LayerDrawable is the Drawable that manages the Drawable list. Each item in the list is drawn in list order, with the last item in the list drawn at the top.

5.1 grammar

The syntax for defining LayerDrawable is as follows:

<?xml version="1.0" encoding="utf-8"? >
<layer-list
    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" 
        android:gravity=["top"|"bottom"|"left"|"right"|"center_vertical"|"fill_vertical"|"center_horizontal"|"fill_horizontal"|"center"|"fill"|"clip_vertical"|"clip_horizontal"/ >
</layer-list>
Copy the code

The LayerDrawable tag is

. It can contain multiple

tags. Each item represents a Drawable.

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
android:id For item id, use “@+id/name“. FindViewById () or activity.findViewById () can be used to find the Drawable
Android :top, Android :right, Android :bottom, Android :left The offset of Drawable relative to View in each direction
android:gravity The position in the container when the size is smaller than the container size

5.2 Usage Examples

The following shows a simple use of LayerDrawable by defining a rounded Drawable with a shaded effect.

define

<?xml version="1.0" encoding="utf-8"? >
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <! Internally define a Drawable-->
    <item
            android:left="2dp"
            android:top="4dp">
        <shape>
            <solid android:color="@android:color/darker_gray" />
            <corners android:radius="10dp" />
        </shape>
    </item>

    <! Drawable-->
    <item
            android:bottom="4dp"
            android:right="2dp"
            android:drawable="@drawable/shape_light">
    </item>
</layer-list>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@android:color/holo_orange_dark"
    tools:context=".LayerDrawableActivity">

    <LinearLayout
            android:orientation="vertical"
            android:background="@drawable/layer_drawable"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:layout_margin="20dp"
            tools:layout_editor_absoluteY="331dp"
            tools:layout_editor_absoluteX="190dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent">

        <TextView android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:textColor="# 000000"
                  android:text="I'm a title......."
                  android:textSize="20sp" />

        <TextView android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:textColor="@android:color/darker_gray"
                  android:text="content content content content content content content content..."
                  android:textSize="16sp" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

rendering

6. LevelListDrawable

LevelListDrawable also represents a Drawable list. Each item in the list has a level value. LevelListDrawable switches between items based on their level.

6.1 grammar

The syntax for defining LevelListDrawable is as follows:

<?xml version="1.0" encoding="utf-8"? >
<level-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:drawable="@drawable/drawable_resource"
        android:maxLevel="integer"
        android:minLevel="integer" />
</level-list>
Copy the code

The LayerDrawable root tag is

. It can contain multiple

tags. Each item represents a Drawable.

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
android:maxLevel Maximum level of the item. The value range is [0, 10000].
android:minLevel Minimum level allowed for this item. Value range: [0, 10000]

6.2 Usage Examples

define

<?xml version="1.0" encoding="utf-8"? >
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:drawable="@drawable/kakarotto1"
            android:maxLevel="0" />

    <item
            android:drawable="@drawable/kakarotto2"
            android:maxLevel="1" />

    <item
            android:drawable="@drawable/kakarotto3"
            android:maxLevel="2" />

    <item
            android:drawable="@drawable/kakarotto4"
            android:maxLevel="3" />

    <item
            android:drawable="@drawable/kakarotto5"
            android:maxLevel="4" />
</level-list>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".GradientDrawableActivity">

    <ImageView
            android:text="Button"
            android:layout_width="230dp"
            android:layout_height="150dp"
            android:src="@drawable/drawable_level_list"
            android:id="@+id/img"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Then control the ImageView level to display the effect:

class LevelListDrawableActivity : AppCompatActivity() {
    lateinit var mImageView: ImageView

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_level_list_drawable)

        mImageView = findViewById(R.id.img)
        for (i in 0.15.) {
            mHandler.sendEmptyMessageDelayed(i, (1000 * i).toLong())
        }
    }

    var mHandler: Handler = object: Handler() {
        override fun handleMessage(msg: Message?).{ msg? .what? .let { mImageView.setImageLevel(it%5)}}}}Copy the code

rendering

7. InsetDrawable

In some scenarios, we may need to have a full-screen background image, but we want to leave some space between the background image and the border. InsetDrawable is a great way to solve this problem.

7.1 grammar

<?xml version="1.0" encoding="utf-8"? >
<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:insetTop="dimension"
    android:insetRight="dimension"
    android:insetBottom="dimension"
    android:insetLeft="dimension" />
Copy the code

The root tag is

, and its attributes mean:

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
Android :insetTop, Android :insetRight, Android :insetBottom, Android :insetLeft Distance of content from each border

7.2 Usage Examples

define

<?xml version="1.0" encoding="utf-8"? >
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:drawable="@drawable/shape_dark"
       android:insetBottom="10dp"
       android:insetTop="10dp"
       android:insetLeft="10dp"
       android:insetRight="10dp" />
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/drawable_inset">

    <TextView
            android:textSize="20sp"
            android:text="TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

rendering

8. ScaleDrawable

ScaleDrawable dynamically scales Drawable in proportion to the level value. When the value of level ranges from 0 to 10000, it is hidden when the value of level is 0. When the level value is 1, the Drawable size is the initialization scale; when the level value is 10000, the Drawable size is 100% scale.

8.1 grammar

The syntax for defining ScaleDrawable is as follows:

<?xml version="1.0" encoding="utf-8"? >
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:scaleGravity=["top"|"bottom"|"left"|"right"|"center_vertical"|"fill_vertical"|"center_horizontal"|"fill_horizontal"|"center"|"fill"|"clip_vertical"|"clip_horizontal"]
    android:scaleHeight="percentage"
    android:scaleWidth="percentage" />
Copy the code

Its root tag is

, and its attributes mean:

android:drawable

Drawable resource that can reference an existing drawable

android:scaleGravity

When the image size is less than the View, set this property value can locate images, you can use “|” symbol combination, the meaning of all the values are:

value instructions
top Place an object on top of its container without changing its size.
bottom Place an object at the bottom of its container without changing its size.
left Place the object on the left edge of its container without changing its size. This is the default value.
right Place the object on the right edge of its container without changing its size.
center_vertical Place an object in the vertical center of its container without changing its size.
fill_vertical Extend the vertical size of the object as needed to fully fit its container.
center_horizontal Place an object in the horizontal center of its container without changing its size.
fill_horizontal Extend the horizontal size of the object as needed to fully fit its container.
center Center an object on the horizontal and vertical axes of its container without changing its size.
fill Extend the vertical size of the object as needed to fully fit its container.
clip_vertical An additional option that can be set to have the top and/or bottom edges of child elements clipped to their container boundaries. Clipping is based on vertical gravity: top gravity clipping the upper edge, bottom gravity clipping the lower edge, neither side clipping at the same time.
clip_horizontal Additional options that can be set to have the left and/or right sides of child elements clipped to their container boundaries. Clipping is based on horizontal gravity: left gravity clipping the right edge, right gravity clipping the left edge, neither side clipping at the same time.

android:scaleHeight

Drawable Specifies the high scale. The higher the value, the smaller the result.

android:scaleWidth

Drawable Specifies the wide scale

8.2 Usage Examples

Here is an example of customizing a variable size background to show the simple use of ScaleDrawable.

define

<?xml version="1.0" encoding="utf-8"? >
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:drawable="@drawable/kakarotto"
       android:scaleHeight="80%"
       android:scaleWidth="80%"
       android:scaleGravity="center" />
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
            android:text="Button"
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="@drawable/drawable_scale"
            android:id="@+id/button"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class ScaleDrawableActivity : AppCompatActivity() {
    lateinit var scaleDrawable: ScaleDrawable
    var curLevel = 0

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scale_drawable)

        scaleDrawable = findViewById<Button>(R.id.button).background as ScaleDrawable
        scaleDrawable.level = 0

        Observable.interval(200. TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe { scaleDrawable.level = curLevel curLevel +=200
                if (curLevel >= 10000) {
                    curLevel = 0
                }
                Log.e("gpj"."level ${curLevel}")}}}Copy the code

rendering

9. ClipDrawable

Like ScaleDrawable, ClipDrawable can dynamically trim Drawable to a certain proportion according to the level value. When the value of level ranges from 0 to 10000, it is hidden when the value of level is 0. When the level value is 1, the Drawable size is the clipping proportion during initialization; when the level value is 10000, the Drawable size is 100% clipping proportion.

9.1 grammar

The syntax for defining ClipDrawable is as follows:

<?xml version="1.0" encoding="utf-8"? >
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:clipOrientation=["horizontal"|"vertical"]
    android:gravity=["top"|"bottom"|"left"|"right"|"center_vertical"|"fill_vertical"|"center_horizontal"|"fill_horizontal"|"center"|"fill"|"clip_vertical"|"clip_horizontal"/ >
Copy the code

The root tag is

, and each attribute has the following meanings:

android:drawable

Drawable resource that can reference an existing drawable

android:clipOrientation

Clipping direction, horizontal indicates clipping in the horizontal direction, vertical indicates clipping in the vertical direction

android:gravity

Gravity matching clipOrientation attributes needed to use, can use “|” symbol combination, the meaning of all the values are:

value instructions
top Place an object on top of its container without changing its size. whenclipOrientation"vertical"Clipping at the bottom of the drawable object.
bottom Place an object at the bottom of its container without changing its size. whenclipOrientation"vertical"Clipping at the top of the drawable object.
left Place the object on the left edge of its container without changing its size. This is the default value. whenclipOrientation"horizontal"Clipped to the right of the drawable object. This is the default value.
right Place the object on the right edge of its container without changing its size. whenclipOrientation"horizontal"Clipped to the left of the drawable object.
center_vertical Place an object in the vertical center of its container without changing its size. The clipping behavior and gravity are"center"When the same.
fill_vertical Extend the vertical size of the object as needed to fully fit its container. whenclipOrientation"vertical"Is not clipped because the drawable fills the vertical space (unless the drawable level is 0, at which point it is not visible).
center_horizontal Place an object in the horizontal center of its container without changing its size. The clipping behavior and gravity are"center"When the same.
fill_horizontal Extend the horizontal size of the object as needed to fully fit its container. whenclipOrientation"horizontal"Is not clipped because the drawable fills the horizontal space (unless the drawable level is 0, at which point it is not visible).
center Center an object on the horizontal and vertical axes of its container without changing its size. whenclipOrientation"horizontal"Cut on the left and right. whenclipOrientation"vertical"Cut at the top and bottom.
fill Extend the vertical size of the object as needed to fully fit its container. Clipping is not done because the drawable fills both horizontal and vertical space (unless the drawable level is 0, at which point it is not visible).
clip_vertical An additional option that can be set to have the top and/or bottom edges of child elements clipped to their container boundaries. Clipping is based on vertical gravity: top gravity clipping the upper edge, bottom gravity clipping the lower edge, neither side clipping at the same time.
clip_horizontal Additional options that can be set to have the left and/or right sides of child elements clipped to their container boundaries. Clipping is based on horizontal gravity: left gravity clipping the right edge, right gravity clipping the left edge, neither side clipping at the same time.

9.2 Usage Examples

define

<?xml version="1.0" encoding="utf-8"? >
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:clipOrientation=["horizontal"|"vertical"]
    android:gravity=["top"|"bottom"|"left"|"right"|"center_vertical"|"fill_vertical"|"center_horizontal"|"fill_horizontal"|"center"|"fill"|"clip_vertical"|"clip_horizontal"/ >
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
            android:text="Button"
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="@drawable/drawable_clip"
            android:id="@+id/button"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class ClipDrawableActivity : AppCompatActivity() {
    lateinit var clipDrawable: ClipDrawable
    var curLevel = 0

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_clip_drawable)

        clipDrawable = findViewById<Button>(R.id.button).background as ClipDrawable
        clipDrawable.level = 0

        Observable.interval(50. TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe { clipDrawable.level = curLevel curLevel +=200
                if (curLevel >= 10000) {
                    curLevel = 0
                }
                Log.e("gpj"."level ${curLevel}")}}}Copy the code

rendering

10. RotateDrawable

Like ScaleDrawable and ClipDrawable, RotateDrawable dynamically rotates a Drawable based on its level value.

10.1 grammar

RotateDrawable is defined as follows:

<?xml version="1.0" encoding="utf-8"? >
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:visible=["true"|"false"]
    android:fromDegrees="integer" 
    android:toDegrees="integer"
    android:pivotX="percentage"
    android:pivotY="percentage" />
Copy the code

The root tag is

and each attribute has the following meanings:

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
android:visible Whether or not visible
android:fromDegrees Rotation starting Angle
android:toDegrees End Angle of rotation
android:pivotX The percentage of places where the center of rotation is on the X-axis
android:pivotY The percentage of the rotation center on the Y-axis

10.2 Usage Examples

The following example shows a simple use of RotateDrawable by defining a rotatable background

define

<?xml version="1.0" encoding="utf-8"? >
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/kakarotto"
        android:fromDegrees="0"
        android:toDegrees="180"
        android:pivotX="50%"
        android:pivotY="50%"/>
Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
            android:text="Button"
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="@drawable/drawable_rotate"
            android:id="@+id/button"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
class RotateDrawableActivity : AppCompatActivity() {
    lateinit var rotateDrawable: RotateDrawable
    var curLevel = 0

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_rotate_drawable)

        rotateDrawable = findViewById<Button>(R.id.button).background as RotateDrawable
        rotateDrawable.level = 0

        Observable.interval(50. TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe { rotateDrawable.level = curLevel curLevel +=200
                if (curLevel >= 10000) {
                    curLevel = 0
                }
                Log.e("gpj"."level ${curLevel}")}}}Copy the code

rendering

11. TransitionDrawable

Sometimes you need to add a gradient effect when switching between two images. In addition to using animation, this can be done easily with TransitionDrawable.

11.1 grammar

<?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>

Copy the code

Its root tag is
, and it can contain multiple

tags. Each item represents a Drawable.

attribute meaning
android:drawable Drawable resource that can reference an existing drawable
android:id For iitem id, use “@+id/name“. FindViewById () or activity.findViewById () can be used to find the Drawable
Android :top, Android :right, Android :bottom, Android :left The offset of Drawable relative to View in each direction

11.2 Usage Examples

Here we define a picture toggle effect that fades in and out to show the basic use of TransitionDrawable.

define

<?xml version="1.0" encoding="utf-8"? >
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/kakarotto1" />
    <item android:drawable="@drawable/kakarotto2" />
</transition>

Copy the code

use

<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
            android:layout_width="230dp"
            android:layout_height="150dp"
            android:background="@drawable/drawable_transition"
            android:id="@+id/img"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Copy the code
class TransitionDrawableActivity : AppCompatActivity() {
    lateinit var disposable: Disposable
    var reverse = false

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_transition_drawable)

        var transitionDrawable = findViewById<ImageView>(R.id.img).background as TransitionDrawable

        Observable.interval(3000, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<Long> {
                override fun onSubscribe(d: Disposable) {
                    disposable = d
                }
                override fun onComplete(a){}override fun onNext(t: Long) {
                    if(! reverse) { transitionDrawable.startTransition(3000)
                        reverse = true
                    } else {
                        transitionDrawable.reverseTransition(3000)
                        reverse = false}}override fun onError(e: Throwable){}})}Copy the code

rendering

Well, that’s all for traditional Drawable, but as Android versions get updated, new members of the Drawable family continue to be added, giving developers more options. In the next installment, I’ll introduce a few members that have been added since Android 5.0(API 21).

Attached: Demo address in the article:Github.com/guanpj/Draw…