8.1.1 Summary of 13 Drawable Types in Android Part 1
Category Android Basic Tutorial
Introduction:
>
Starting from this section, we will learn some basic knowledge of drawing and animation in Android, laying the foundation for our customizations in the advanced section! The first topic we will delve into is Drawable in Android! Android provides us with up to 13 types of Drawable, and in this section, we will go through each one!
Drawable Resource Usage Notes
>
Drawable is divided into two types: One is our ordinary image resource, which we usually place under the res/mipmap directory in Android Studio, unlike the old Eclipse! Also, if we switch the project to Android project mode, we can directly drop images into the mipmap directory, and AS will automatically categorize them into hdpi, xhdpi, etc.! The other is our XML-formatted Drawable resource, which we usually place under the res/drawable directory, such as the most common button click background switch Selector!
In XML, we can directly set Drawable via @mipmap or @drawable, for example: android:background = "@mipmap/iv_icon_zhu" / "@drawable/btn_back_selector" In Java code, we can obtain drawable resources through Resource's getDrawable(R.mipmap.xxx). If we are setting the background for a certain control, such as ImageView, we can directly call control.getDrawable() to get the drawable object!
The resource names in Android's drawable have constraints, they must be: [a-z0-9_.] (i.e., only letters, numbers, and * and .), and cannot start with a number, otherwise, the compilation will report an error: Invalid file name: must contain only [a-z0-9* .]! Lowercase! Lowercase! Lowercase! — Important things are said three times~
Okay, these are the main points to pay attention to. Next, let's learn about the 13 types of Drawable provided by Android!
1. ColorDrawable
>
The simplest type of Drawable, when we draw a ColorDrawable onto the Canvas (canvas), it will fill the Paint with a fixed color, and then draw a single-color area onto the canvas!
1). Define ColorDrawable in Java:
ColorDrawable drawable = new ColorDrawable(0xffff2200);
txtShow.setBackground(drawable);
2). Define ColorDrawable in xml:
<?xml version="1.0" encoding="utf-8"?>
<color
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FF0000"/>
Of course, the above usages are not commonly used. More often, we create a color.xml file under the res/values directory and write the color values we need into it. When needed, we get the corresponding values through @color, for example:
3). Create a color.xml file
For example:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="material_grey_100">#fff5f5f5</color>
<color name="material_grey_300">#ffe0e0e0</color>
<color name="material_grey_50">#fffafafa</color>
<color name="material_grey_600">#ff757575</color>
<color name="material_grey_800">#ff424242</color>
<color name="material_grey_850">#ff303030</color>
<color name="material_grey_900">#ff212121</color>
</resources>
Then, if in an xml file, we can get the corresponding color value through @color/xxx. If in Java:
int mycolor = getResources().getColor(R.color.mycolor);
btn.setBackgroundColor(mycolor);
ps: Also, note that if we define the color value directly in Java, we need to add 0x, and we cannot omit the transparency:
int mycolor = 0xff123456;
btn.setBackgroundColor(mycolor);
4). Use system-defined colors:
For example: BLACK (black), BLUE (blue), CYAN (cyan), GRAY (gray), GREEN (green), RED (red), WRITE (white), YELLOW (yellow)! Usage: btn.setBackgroundColor(Color.BLUE); You can also get the system color and then set it:
int getcolor = Resources.getSystem().getColor(android.R.color.holo_green_light);
btn.setBackgroundColor(getcolor);
Usage in xml: android:background="@android:color/black"
5). Use the static method argb to set the color:
>
Android uses an int type data to represent the color value, usually in hexadecimal, starting with 0x. The color value is defined by the transparency alpha and the three primary colors RGB (red, green, blue), starting with "#", followed by: transparency-red-green-blue; eg: #RGB #ARGB #RRGGBB #AARRGGBB txtShow.setBackgroundColor(Color.argb(0xff, 0x00, 0x00, 0x00));
2. NinePatchDrawable
>
It's the .9 image. In the previous section 1.6 How to Use .9 (Nine-Sister) Images, we have explained in detail how to create .9 images! The Android Framework uses an efficient graphics optimization algorithm when displaying .9 images, and we don't need special handling to achieve adaptive image stretching. Also, note the following when using AS:
- .9 images cannot be placed under the mipmap directory, but need to be placed under the drawable directory!
- In AS, .9 images must have black lines, otherwise, the compilation will not pass. This morning, my cousin Jun mentioned in the group that the graphic designer in his company gave him a .9 image without black lines, saying it was made using a certain software, and it could be used in Eclipse. Yes, it's a .9 image without black lines, wow, but when I switched to AS, the compilation directly did not pass! I feel that one of the criteria for AS to recognize .9 images is the need for black dots or black lines! Also, my cousin gave a method to remove black lines: How to Remove Black Dots/Lines from 9patch(.9). I haven't tried it myself, so you can try it if you're interested, but do black lines really look that bad... I don't have OCD, so I don't think so! Also, there's one more thing, when decompressing someone else's apk and taking .9 materials, you may find that there are no black lines, and it will also report an error! If you want to take out .9 materials with black lines, you need to decompile the apk instead of directly decompressing it! Decompile it as mentioned before, so I won't go into details here!
Next, let's introduce two things that are not very useful:
Define NinePatchDrawable in xml:
<!--pic9.xml-->
<!--Parameters are: referenced .9 image, whether to dither the bitmap-->
<?xml version="1.0" encoding="utf-8"?>
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/dule_pic"
android:dither="true"/>
Use Bitmap to wrap .9 image:
<!--pic9.xml-->
<!--Parameters are: referenced .9 image, whether to dither the bitmap-->
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/dule_pic"
android:dither="true"/>
3. ShapeDrawable
>
A Drawable of shape, defining basic geometric shapes, such as (rectangle, circle, line, etc.), the root element is <shape../> There are many related nodes, as follows:
① <shape >:
~visible : Set whether it is visible
~shape : Shape, optional: rectangle (rectangle, including square), oval (ellipse, including circle), line (line segment), ring (ring)
~innerRadiusRatio : Valid when shape is ring, indicating the ratio of the inner radius to the radius, if innerRadius is set, it will be ignored
~innerRadius : Valid when shape is ring, indicating the size of the inner radius of the ring
~thicknessRatio : Valid when shape is ring, indicating the ratio of the ring thickness to the radius
~thickness : Valid when shape is ring, indicating the thickness of the ring, i.e., the difference between the outer radius and the inner radius
~useLevel : Valid when shape is ring, indicating whether to allow displaying part of the ring according to the level
②<size >:
~width : Width of the graphic shape
~height : Height of the graphic shape
③<gradient >: Will be explained later in GradientDrawable~
④<solid >
~color : Background fill color, setting solid will override all effects set by gradient!!!!!
⑤<stroke >
~width : Width of the border
~color : Color of the border
~dashWidth : Length of the dashed segment of the border
~dashGap : Gap of the dashed segment of the border
⑥<conner >
~radius : Corner radius, applicable to the upper left, upper right, lower left, and lower right corners
~topLeftRadius , topRightRadius , BottomLeftRadius , tBottomRightRadius : Upper left, upper right, lower left, lower right corner values, set as needed!
⑦<padding >
left, top, right, bottm: Padding in the left, top, right, bottom directions!
Usage example: 2.3.1 TextView (Text Box) Detailed Explanation
4. GradientDrawable
>
A Drawable with a gradient area, which can achieve linear gradient, radial gradient, and tiled gradient effects Core node: <gradient />, with the following optional attributes:
startColor : Starting color of the gradient
centerColor : Middle color of the gradient
endColor : Ending color of the gradient
type: Gradient type, optional (linear, radial, sweep), linear gradient (can set gradient angle), radial gradient (middle spreads outwards), tiled gradient
centerX: X coordinate of the gradient center, value range: 0~1
centerY: Y coordinate of the gradient center, value range: 0~1
angle: Only valid for linear gradients, represents the gradient angle, must be a multiple of 45
gradientRadius: Only valid for radial and sweep gradients, radial must be set, represents the radius of the gradient effect
useLevel: Determines whether to draw the gradient effect based on level
Code Example: (Demonstration of three gradient effects):
Runtime Effect Diagram:
First, create three gradient XML files under drawable:
(Linear Gradient) gradient_linear.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<gradient
android:angle="90"
android:centerColor="#FFEB82"
android:endColor="#35B2DE"
android:startColor="#DEACAB" />
<stroke
android:dashGap="5dip"
android:dashWidth="4dip"
android:width="3dip"
android:color="#fff" />
</shape>
(Radial Gradient) gradient_radial.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dip"
android:shape="ring"
android:thickness="70dip"
android:useLevel="false" >
<gradient
android:centerColor="#FFEB82"
android:endColor="#35B2DE"
android:gradientRadius="70"
android:startColor="#DEACAB"
android:type="radial"
android:useLevel="false" />
</shape>
(Sweep Gradient) gradient_sweep.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadiusRatio="8"
android:shape="ring"
android:thicknessRatio="3"
android:useLevel="false" >
<gradient
android:centerColor="#FFEB82"
android:endColor="#35B2DE"
android:startColor="#DEACAB"
android:type="sweep"
android:useLevel="false" />
</shape>
Calling the three drawables in activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/txtShow1"
android:layout_width="200dp"
android:layout_height="100dp"
android:background="@drawable/gradient_linear" />
<TextView
android:id="@+id/txtShow2"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/gradient_radial" />
<TextView
android:id="@+id/txtShow3"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/gradient_sweep" />
</LinearLayout>
That's it, quite simple! Of course, if you want to draw more complex shapes, XML files alone are not enough. More complex effects require Java code to achieve. Below is a source code example from the web:
Runtime Effect Diagram:
Implementation Code:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private ShapeDrawable[] mDrawables;
private static Shader makeSweep() {
return new SweepGradient(150, 25,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
null);
}
private static Shader makeLinear() {
return new LinearGradient(0, 0, 50, 50,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
null, Shader.TileMode.MIRROR);
}
private static Shader makeTiling() {
int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
Bitmap.Config.ARGB_8888);
return new BitmapShader(bm, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
}
private static class MyShapeDrawable extends ShapeDrawable {
private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public MyShapeDrawable(Shape s) {
super(s);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
public Paint getStrokePaint() {
return mStrokePaint;
}
@Override protected void onDraw(Shape s, Canvas c, Paint p) {
s.draw(c, p);
s.draw(c, mStrokePaint);
}
}
public SampleView(Context context) {
super(context);
setFocusable(true);
float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
RectF inset = new RectF(6, 6, 6, 6);
float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
Path path = new Path();
path.moveTo(50, 0);
path.lineTo(0, 50);
path.lineTo(50, 100);
path.lineTo(100, 50);
path.close();
mDrawables = new ShapeDrawable[7];
mDrawables[0] = new ShapeDrawable(new RectShape());
mDrawables[1] = new ShapeDrawable(new OvalShape());
mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
null));
mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
null));
mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
innerR));
mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
mDrawables[0].getPaint().setColor(0xFFFF0000);
mDrawables[1].getPaint().setColor(0xFF00FF00);
mDrawables[2].getPaint().setColor(0xFF0000FF);
mDrawables[3].getPaint().setShader(makeSweep());
mDrawables[4].getPaint().setShader(makeLinear());
mDrawables[5].getPaint().setShader(makeTiling());
mDrawables[6].getPaint().setColor(0x88FF8844);
PathEffect pe = new DiscretePathEffect(10, 4);
PathEffect pe2 = new CornerPathEffect(4);
mDrawables[3].getPaint().setPathEffect(
new ComposePathEffect(pe2, pe));
MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
msd.getStrokePaint().setStrokeWidth(4);
}
@Override protected void onDraw(Canvas canvas) {
int x = 10;
int y = 10;
int width = 400;
int height = 100;
for (Drawable dr : mDrawables) {
dr.setBounds(x, y, x + width, y + height);
dr.draw(canvas);
y += height + 5;
}
}
}
}
- 2.5.9 Detailed Explanation of AlertDialog
- 2.6.0 Basic Usage of Other Common Dialogs
- 2.6.1 Basic Usage of PopupWindow
- 2.6.2 Menu
- 2.6.3 Simple Usage of ViewPager
- 2.6.4 Simple Usage of DrawerLayout
- 3.1.1 Event Handling Mechanism Based on Listeners
- 3.2 Event Handling Mechanism Based on Callbacks
- 3.3 Analysis of Handler Message Passing Mechanism
- 3.4 TouchListener vs OnTouchEvent + Multi-touch
- 3.5 Listening for Content Changes in EditText
- 3.6 Responding to System Setting Events (Configuration Class)
- 3.7 AsyncTask Asynchronous Tasks
- 3.8 Gestures
- 4.1.1 Introduction to Activity
- 4.1.2 Getting Started with Activity
- 4.1.3 Advanced Activity
- 4.2.1 Introduction to Service
- 4.2.2 Advanced Service
- 4.2.3 Expert Service
- 4.3.1 Basic BroadcastReceiver
- 4.3.2 In-depth BroadcastReceiver
- 4.4.1 Introduction to ContentProvider
- 4.4.2 Further Exploration of ContentProvider - Document Provider
- 4.5.1 Basic Usage of Intent
- 4.5.2 Passing Complex Data with Intent
- 5.1 Basic Overview of Fragment
- 5.2.1 Fragment Example - Bottom Navigation Bar Implementation (Method 1)
- 5.2.2 Fragment Example - Bottom Navigation Bar Implementation (Method 2)
- 5.2.3 Fragment Example - Bottom Navigation Bar Implementation (Method 3)
- 5.2.4 Fragment Example - Bottom Navigation Bar + ViewPager Page Swipe
- 5.2.5 Fragment Example - Simple Implementation of News/Shopping App List Fragment
- 6.1 Data Storage and Access - File Storage and Reading
- 6.2 Data Storage and Access - SharedPreferences for Saving User Preferences
- 6.3.1 Data Storage and Access - Introduction to SQLite Database
- 6.3.2 Data Storage and Access - Further Exploration of SQLite Database
- 7.1.1 Android Network Programming and HTTP Protocol Learning
- 7.1.2 Learning Android HTTP Request and Response Headers
- 7.1.3 Android HTTP Request Method: HttpURLConnection
- 7.1.4 Android HTTP Request Method: HttpClient
- 7.2.1 Android XML Data Parsing
- 7.2.2 Android JSON Data Parsing
- 7.3.1 Android File Upload
- 7.3.2 Android File Download (1)
- 7.3.3 Android File Download (2)
- 7.4 Android Calling WebService
- 7.5.1 Basic Usage of WebView
- 7.5.2 WebView and JavaScript Interaction Basics
- 7.5.3 WebView Considerations After Android 4.4
- 7.5.4 WebView File Download
- 7.5.5 WebView Cache Issues
- 7.5.6 WebView Handling Webpage Error Codes
- 7.6.1 Socket Network Basics Preparation
- 7.6.2 TCP Protocol Socket Communication (1)
- 7.6.3 TCP Protocol Socket Communication (2)
- 7.6.4 UDP Protocol Socket Communication
- 8.1.1 Summary of 13 Drawable Types in Android Part 1
- 8.1.2 Summary of 13 Drawable Types in Android Part 2
- 8.1.3 Summary of 13 Drawable Types in Android Part 3
- 8.2.1 Comprehensive Analysis of Bitmap Part 1
- 8.2.2 OOM Issues Caused by Bitmap
- 8.3.1 Detailed Explanation of Three Drawing Tools
- 8.3.2 Drawing Tool Practical Examples
- 8.3.3 Paint API - MaskFilter
- 8.3.4 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 1)
- 8.3.5 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 2)
- 8.3.6 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 3)
- 8.3.7 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 4)
- 8.3.8 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 5)
- 8.3.9 Paint API - ColorFilter (Color Filter) (1/3)
- 8.3.10 Paint API - ColorFilter (Color Filter) (2/3)
- 8.3.11 Paint API - ColorFilter (Color Filter) (3/3)
- 8.3.12 Paint API - PathEffect (Path Effect)
- 8.3.13 Paint API - Shader (Image Rendering)
- 8.3.14 Paint Enum/Constants and ShadowLayer Shadow Effect
- 8.3.15 Paint API - Typeface (Font Style)
- 8.3.16 Canvas API Detailed Explanation (Part 1)
- 8.3.17 Canvas API Detailed Explanation (Part 2) - Clipping Methods Collection
- 8.3.18 Canvas API Detailed Explanation (Part 3) - Matrix and drawBitmapMesh
- 8.4.1 Android Animation Collection - Frame Animation
- 8.4.2 Android Animation Collection - Tween Animation
- 8.4.3 Android Animation Collection - Property Animation - Introduction
- 8.4.4 Android Animation Collection - Property Animation - Further Exploration
- 9.1 Using SoundPool to Play Sound Effects (Duang~)
- 9.2 MediaPlayer for Audio and Video Playback
- 9.3 Using Camera to Take Photos
- 9.4 Using MediaRecord to Record Audio
- 10.1 TelephonyManager (Phone Manager)
- 10.2 SmsManager (SMS Manager)
- 10.3 AudioManager (Audio Manager)
- 10.4 Vibrator (Vibrator)
- 10.5 AlarmManager (Alarm Service)
- 10.6 PowerManager (Power Service)
- 10.7 WindowManager (Window Management Service)
- 10.8 LayoutInflater (Layout Service)
- 10.9 WallpaperManager (Wallpaper Manager)
- 10.10 Sensor Series (1) - Introduction
- 10.11 Sensor Series (2) - Orientation Sensor
- 10.12 Sensor Series (3) - Accelerometer/Gyroscope Sensor
- 10.12 Sensor Series (4) - Understanding Other Sensors
- 10.14 Android GPS Introduction
- 11.0《2015 Latest Android Basic Tutorial》Completion Celebration~
- 12.1 Android Practice: DrySister Viewing Girls App (Version 1) - Project Setup and Simple Implementation
- 12.2 DrySister Viewing Girls App (Version 1) - 2. Parsing Backend Data
- 12.3 DrySister Viewing Girls App (Version 1) - 3. Image Loading Optimization (Writing an Image Caching Framework)
- 12.4 DrySister Viewing Girls App (Version 1) - 4. Adding Data Caching (Introducing SQLite)
- 12.5 DrySister Viewing Girls App (Version 1) - 5. Code Review, Adjustment, and Logging Class Writing
- 12.6 DrySister Viewing Girls App (Version 1) - 6. Icon Creation, Obfuscation, Signing, Packaging, APK Slimming, App Release