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 aRectShape
.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
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…