preface
This post has been posted on my Github blog. Welcome to my humble abode:
My GIthub blog
Study list:
Drawable
Introduction to theDrawable
classification- The custom
Drawable
1. Why learn Drawable?
There are many kinds of drawables, all of which represent the concept of an image, but they are not all pictures. In practice, Drawable is often used as a background for a View.
Drawable makes it easy to create special UI effects, which are extremely important in UI-related development. In the face of UI designers designed various button click effects, dynamic effects, gradient effects, beautiful is beautiful, we programmers tend to roar: “you feel comfortable, we!!” Don’t panic, learn Drawable, you will have a variety of effects at your fingertips, know what to expect!!
Also, Drawable has its own advantages in development:
-
It is simple to use and costs less than custom views
-
Non-image drawables take up less space and are helpful in reducing the size of APK
To sum up, master Drawable, go all over the world is not afraid! (jia DE)
Two. Induction of core knowledge points
2.1 Drawable
Introduction to the
Q1: The Drawable class is abstract and is the base class for all Drawable classes. The inheritance relationship is as follows:
Q2:Drawable
- Of the root node that creates the required DrawablexmlAnd then through the
@drawable/xxx
Into the layout. (common)
- Normal controls (not ImageView) are Settings
background
- ImageView is to set up
src
- Java code: New a required Drawable and set related attributes, and finally loaded into the layout.
Q3: What is the internal width and height?
- Obtaining method:
getIntrinsicWidth()
andgetIntrinsicHeight()
Note:
- Not all
Drawable
Both have internal width/height- Formed by pictures
Drawable
The internal width/height is the width/height of the image.- Made of color
Drawable
By default, there is no concept of internal width/height (unless size is specified).- The internal width and height are not equal to the size,
Drawable
No concept of sizeDrawable
Be used as abackground
Is automatically stretched to the same size as View;Drawable
Be used as asrc
When storing the original drawing size scale, it will not be stretched
2.2 Drawable
species
2.2.1 BitmapDrawable
- Represents a picture
- Common attributes:
bitmap
|- src="@drawable/res_id" |- antialias="[true | false]"
|- dither="[true | false]" |- filter="[true | false]"
|- tileMode="[disabled | clamp | repeat | mirror]"
|- gravity="[top | bottom | left | right | center_vertical |
| fill_vertical | center_horizontal | fill_horizontal |
| center | fill | clip_vertical | clip_horizontal]"
Copy the code
src
: Resource ID of the imageantialias
: Indicates whether to enable the pictureanti-aliasing. If enabled, the image will be smoother and less sharp. Should be enabled.dither
: Enable or notjitterThe effect. Enabled to allow high quality images to appear on low quality screens without distortion, should be enabled.filter
: Enable or notfilterThe effect. When the image size is stretched or compressed, it can be turned on to maintain a good display and should be turned ontileMode
: Tile mode. After the openinggravity
Failure; Specific meanings of the optional values:
optional meaning disable Default value, tiling mode is disabled mirror Mirror projection effect in horizontal and vertical directions repeat Tiling effect in horizontal and vertical directions clamp The pixels around the image spread out into other areas Specific effects:
gravity
: If the bitmap is smaller than the container, you can set the relative position of the bitmap in the container. Specific meanings of the optional values:
- Usage: The following two methods have the same effect, as shown in the previous screenshot of the mirror.
a.xml:
Create bg_tilemode_mirror.xml in the Drawable folder <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:src="@mipmap/ic_launcher" android:tileMode="mirror" > </bitmap> // Set the View background in activity_main.xml<View android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_tilemode_mirror" /> Copy the code
B.J ava code:
// Create BitmapDrawable in MainActivity Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher); BitmapDrawable bitDrawable = new BitmapDrawable(bitmap); bitDrawable.setDither(true); bitDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); // Load the myLayout layout LinearLayout myLayout = (LinearLayout) findViewById(R.id.mylayout); myLayout.setBackgroundDrawable(bitDrawable); Copy the code
2.2.2 NinePatchDrawable
- Said a
9.
Formatted picture - Function: can automatically scale according to the required width/height and guarantee no distortion.
- Production method and principle: can refer to blog: 9Patch/NinePatch details and use
- Common attributes: and 2.2.1
BitmapDrawable
The same - Usage: Java code is not recommended
NinePatchDrawable
, it is recommended to use XML definition, see the code below.
// Create bg_nine_patch.xml in the Drawable folder
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:src="@drawable/box"
>
</nine-patch>
// Set the EditText background in activity_main.xml<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_nine_patch"
/>
Copy the code
2.2.3 ShapeDrawable
- Can represent solid color base geometry with gradient effect (rectangle, circle, line, etc.)
- The root node
shape
The child nodecorners
,gradient
,padding
,size
,solid
,stroke
<?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:topLeftRaidus="integer"
android:topRightRaidus="integer"
android:bottomLeftRaidus="integer"
android:bottomRightRaidus="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="color"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type="[linear | radial | sweep]"
android:useLevel="[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" />
Copy the code
Next, the meanings of attributes under each node are explained respectively:
Q1 shape: Shape of the graph, available values are:
- Rectangle: Default value.
- Oval (ellipse)
- Line:
Note: Information such as the width and color of the line must be specified by the stroke tag.
- Ring:
- Note:Must bethrough
stroke
Tag to specify information such as the width and color of the ring line.- The ring has several additional properties, as shown below:
Q2 corners: Indicates the angles of the four rounded corners of the shape. This only applies to rectangles.
radius
: Set the same Angle for all four angles simultaneously. The priority is lower than the following four attributes.topLeftRadius
: Angle of the upper left cornertopRightRadius
: Angle in the upper right cornerbottomLeftRadius
: Angle of the lower left cornerbottomRightRadius
: Angle at the lower right corner
Q3:gradient: Gradient effect, and solid solid color filling is mutually exclusive.
angle
: Gradient Angle.
- The default is 0
- The value must be a multiple of 45.
- 0 means left to right, 90 means bottom to top.
centerX
: The X coordinate of the center of the gradientcenterY
: Y coordinate of the center of the gradientstartColor
: The initial color of the gradientcenterColor
: Intermediate color of gradientendColor
: End color of the gradientgradientRadius
: Gradient radius. Only when theandroid:type="radial"
Effective whenuseLevel
: usually false when Drawable is usedStateListDrawable
When is truetype
: Category of gradients. Optional value:
linear
(Linear gradient) : Defaultradial
(Radiation gradient) : Need to cooperateandroid:gradientRadius
Attributes are used together.sweep
(Scan line gradient) :
padding
: The distance from the surrounding blank.size
: The inherent size of the graph, not the final size
Android: Width and Android: Height set the shape width and height respectively.
solid
: Solid color fill.
Android :color: Specifies the fill color.
stroke
: stroke. Attribute Meaning:
The attribute of the stroke | role |
---|---|
width | Width of stroke |
color | Stroke color |
dashWidth | The width of the dotted line |
dashGap | The space between the dotted lines |
2.2.4 LayerDrawable
- Represents a hierarchical set of drawables, with different drawables placed on different layers to achieve a superimposed effect.
- The root node
layer-list
, common attributes:
layer-list
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
Copy the code
Note: Each set of drawables is configured by the item node. A layer-list can contain multiple items, following the principle that the lower item overwrites the upper item.
A. dreable: the referenced bitmap resource ID. If it is empty, a child node of type Drawable is required.
B.i d: layer id.
C. ft: The left margin of the layer relative to the container.
D. light: The right margin of the layer relative to the container.
E. stop: Top distance of the layer relative to the container.
F. Bottom: Bottom distance of the layer relative to the container.
- Example: Simple overlay of bitmap:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
<item
android:left="20dp"
android:top="30dp">
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
<item
android:left="70dp"
android:top="80dp">
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
</layer-list>
Copy the code
2.2.5 StateListDrawable
- Represents a collection of drawables, each of which corresponds to a state of the View.
- The root node
selector
, common attributes:
selector
|-constantSize="[true | false]" |-dither="[true | false]"
|-variablePadding="[true | false]"
|- item | |- drawable="@drawable/drawable_id" | |- state_pressed="[true | false]" | |- state_focused="[true | false]"
| |- state_selected="[true | false]" | |- state_hovered="[true | false]"
| |- state_checked="[true | false]" | |- state_checkable="[true | false]"
| |- state_enabled="[true | false]" | |- state_activated="[true | false]"
| |- state_window_focused="[true | false]"|Copy the code
A.selector
:
constantSize
:The inherent sizeIs it constant?
The default is false, indicating that the intrinsic size changes with the state.
If set to true, the inherent size is fixed and is the maximum inherent size of all internal drawables.
dither
: Enable or notjitterThe effect. Turned on to allow high quality images to be compared to low quality images without distortion on the screen. This function is enabled by default.variblePadding
: itspaddingWhether it changes with the state.
- The default is false, indicating that the padding is a fixed value and is the maximum padding of all Drawable within it.
- True means that the padding changes as the state changes.
B.item
:
drawable
: indicates the id of the referenced bitmap resource.- Properties that represent various states:
state | meaning |
---|---|
State_pressed (used) | Press the state |
state_focused | You’ve got focus |
state_selected | Select the View |
state_checked | Apply tocheckBox |
state_enabled | Indicates available status |
- Example:
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="false" android:dither="true" android:variablePadding="false">
<item android:drawable="@drawable/red_bg" android:state_pressed="false" />
<item android:drawable="@color/black_bg" android:state_pressed="true" />
</selector>
Copy the code
2.2.6 LevelListDrawable
- Represents a collection of drawables, one for each Drawable in the collectionlevelThe concept of. Toggle specific by setting different levels
Drawable
- The root node
level-list
, common attributes:
level-list
|- item
| |- drawable="@drawable/drawable_id"
| |- maxLevel="integer"
| |- minlevel="integer"
Copy the code
drawable
: indicates the id of the referenced bitmap resource.maxLevel
: Maximum value. The value ranges from 0 to 10000. The default value is 0. (common)minlevel
: Minimum value. The value ranges from 0 to 10000. The default value is 0.
-
How to use it: Whether implemented in XML or code, as a View background, you need to call setLevel() in Java code; To be an ImageView foreground, call setImageLevel().
-
Loading rule: An item is loaded when its Android :maxLevel equals the value set by setLevel. If none matches, none is displayed.
-
Example:
// Create bg_level.xml in Drawable folder <level-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:maxLevel="1" android:drawable="@drawable/image1" /> <item android:maxLevel="2" android:drawable="@drawable/image2" /> <item android:maxLevel="3" android:drawable="@drawable/image3" /> </level-list> // Set the ImageView background in activity_main.xml<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/bg_level"/> SetImageLevel () ImageView ImageView = (ImageView) findViewById(R.idmage); imageView.setImageLevel(2);Copy the code
Result: The ImageView background is imagE2.
2.2.7 TransitionDrawable
- A subclass of LayerDrawable that fades in and out between two layers of Drawable.
- The root node
transition
, common attributes andLayerDrawable
The same, not to repeat.
transition
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
Copy the code
-
How to use: Whether implemented in XML or code, if used as the View background, you need to call startTransition() method in Java code to start the animation of switching between two layers, or you can call reverseTransition() method to switch in the opposite direction.
-
Example:
// Create bg_tran.xml in the Drawable folder
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image1"/>
<item android:drawable="@drawable/image2"/>
</transition>
// Set it to ImageView SRC in activity_main.xml<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_tran"
android:src="@drawable/bg_tran"/>
// Call startTransition() ImageView ImageView = (ImageView) findViewById(R.idmage); TransitionDrawable td = (TransitionDrawable) imageView.getDrawable(); TransitionDrawable td2 = (TransitionDrawable) imageView.getBackground(); td.startTransition(3000); td2.startTransition(3000);Copy the code
Result: The ImageView background changes from Image1 to Image2.
2.2.8 InsetDrawable
- Insert a Drawable inside another Drawable with some space around it.
Unlike the padding property of Drawable, the padding represents the margin between the content of the Drawable and the Drawable itself. InsetDrawable represents the margin between the Drawable and the container.
- The root node
inset
, common attributes:
inset
|- drawable="@drawable/drawable_id"
|- visible="[true | false]"
|- insetTop="dimension"
|- insetLeft="dimension"
|- insetRight="dimension"
|- insetBottom="dimension"
|
Copy the code
drawable
: indicates the id of the referenced bitmap resource.visible
: Whether to leave a margin. (After testing, it is found that setting true/false works the same….)insetTop
: Sets the top distance from the container. And the same goes for everything else.
- Application scenario: When the control needs a background smaller than the actual border.
- Example:
// Create in the drawable folder
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/image"
android:insetBottom="40dp"
android:insetLeft="10dp"
android:insetRight="30dp"
android:insetTop="20dp"
android:visible="true">
</inset>
Copy the code
- Is it possible to specify the background for a LinearLayout that fills the entire screen so that the background does not fill the screen?
Answer: You can specify an image using an Inset image resource, and then use an embedded image resource just like a normal image resource
2.2.9 ScaleDrawable
- Indicates that Drawable is scaled to a certain scale.
- The root node
scale
, common attributes:
scale
|- drawable="@drawable/drawable_id"
|- scaleGravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- scaleWidth="percentage"
|- scaleHeight="percentage"
|
Copy the code
drawable
: indicates the id of the referenced bitmap resource.scaleGravity
: equal to BitmapDrawableandroid:gravity
.scaleWidth
/android:scaleHeight
: Specifies the Drawable width/height scale to be usedThe percentageIn the form of.
- How to use: Whether implemented in XML or code, as a View background, need to be called in Java code
setLevel()
Method to control the Drawable level.
- Level The value ranges from 0 to 10000
- The default value is 0: invisible. 1 to 10000: Visible
- general
level
Set it to 1
- Example: To reduce an image to 30% of its original size:
// Create bg_scale.xml in the drawable folder
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_test"
android:scaleGravity="center"
android:scaleHeight="70%"
android:scaleWidth="70%"/>
// Set the ImageView background in activity_main.xml<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg_scale"/>
// Call setLevel() ImageView ImageView = (ImageView) findViewById(R.idmage); ScaleDrawable scaleDrawable = (ScaleDrawable) imageView.getDrawable(); scaleDrawable.setLevel(1);Copy the code
2.2.10 ClipDrawable
- Clipping a Drawable
- The root node
clip
, common attributes:
scale
|- drawable="@drawable/drawable_id"
|- gravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- clipOrientation="[vertical | horizontal]"
|
Copy the code
drawable
: indicates the id of the referenced bitmap resource.gravity
: represents the alignment and needs to be worked on with the clipOrientation. Meanings of the optional values:
clipOrientation
: indicates the clipping direction. The value can be horizontal or vertical.
- How to use: Whether implemented in XML or code, as a View background, need to be called in Java code
setLevel()
Method to control the size of visible area.
- Level The value ranges from 0 to 10000.
- 0: completely clipped, that is, invisible. 10000: indicates no tailoring.
level
The larger the size, the larger the visible area.- general
level
Set it to 1
- Additional examples: The use of ClipDrawable in Android, interested readers can understand
2.3 Customizing Drawable
- At the heart of how it works
draw()
: system call Drawabledraw()
To draw the background of the View or the image of the ImageView. - It is often not necessary to customize a Drawable because you cannot use a custom Drawable in XML, which reduces its scope.
- To create a custom Drawable, you must override it
draw()
,setAlpha()
,setColorFilter()
,getOpacity()
The following is an example of a custom Drawable:
// Customize Drawable
public class CustomDrawable extends Drawable {
<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;" >private</span> Paint mPaint;Copy the code
public CustomDrawable(int color) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
final Rect rect = getBounds();
float cx = rect.exactCenterX();
float cy = rect.exactCenterY();
canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override public int getOpacity(a) { returnPixelFormat.TRANSLUCENT; }}Copy the code
- When a custom Drawable has an inherent size (Drawable is a picture), it is best to override it
getIntrinsicWidth()
andgetIntrinsicHeight()
Because it affects the wrAP_content layout of the View.
Note: The internal size of a Drawable is not equal to the actual size of the Drawable, which is available via getBounds() and is generally the same size as the View.
3. Knowledge development
Congratulations to you! Now that you’ve seen it, you already have some idea of Drawable! This article covers only the types commonly used in Drawable, not all of them, and only XML creation.
However, I have prepared some dry stuff (a blog post) for curious readers, which details the various types of Drawable, the various methods of creating Drawable, and is generally well written. Directions: Summary of Drawable subclass usage.
Here’s a look at Drawable that this article hasn’t covered yet:
If the article is a little help to you, I hope you can click on it. Your click on it is my motivation
References:
- Exploring the Art of Android Development
- 9Patch/NinePatch details and use
- Use of ClipDrawable in Android
- Drawable subclass usage summary
- Point refined art | the development of the Drawable
- Android ImageView uses posture correctly
- InsetDrawable,
- Android embedded image InsetDrawable usage
This article is formatted using MDNICE