8.3.12 Paint API - PathEffect (Path Effect)
Category Android Basic Tutorial
Introduction:
>
This section continues to explore the Paint API - PathEffect, where we set the style of the paint to Stroke. This allows us to draw shapes composed of lines. Sometimes these lines may appear monotonous, such as wanting to convert them into dashed lines or making the corners of the paths smoother. In such cases, you can consider using PathEffect to achieve these effects!
Official API documentation: PathEffect. Upon reviewing the documentation, you'll find that PathEffect, like the previously learned MaskFilter and ColorFilter, has very few usable methods.
We typically use its six subclasses:
- ComposePathEffect
- CornerPathEffect
- DashPathEffect
- DiscretePathEffect
- PathDashPathEffect
- SumPathEffect
Below, we analyze their purposes and constructor methods one by one!
1. Subclass Purpose and Constructor Parameter Analysis:
1) CornerPathEffect
CornerPathEffect(float radius)
>
Smooths the angles between connected segments of the path, creating a rounded effect. The radius specifies the radius of the rounding arc.
2) DashPathEffect
DashPathEffect(float[] intervals, float phase)
>
Converts the path's segments into dashed lines. The intervals array defines the lengths of the dashes and gaps, and must have at least two elements. The phase is the offset at which to start the dash pattern.
3) DiscretePathEffect
DiscretePathEffect(float segmentLength, float deviation)
>
Scatters the path's segments, creating a fragmented effect. The segmentLength specifies the maximum length of each segment, and deviation is the amount of random deviation applied to each segment.
4) PathDashPathEffect
PathDashPathEffect(Path shape, float advance, float phase, PathDashPathEffect.Style style)
>
Fills the current path with a shape. The shape is the path used for filling, advance is the spacing between shapes, and style is an enum that can be ROTATE, MORPH, or TRANSLATE.
- ROTATE: The shape rotates to align with the direction of the next segment.
- MORPH: The shape morphs to connect with the next segment.
- TRANSLATE: The shape translates to connect with the next segment.
5) ComposePathEffect
ComposePathEffect(PathEffect outerpe, PathEffect innerpe)
>
Combines two effects. It first applies innerpe, then adds outerpe on top of it.
6) SumPathEffect
SumPathEffect(PathEffect first, PathEffect second)
>
Superimposes two effects. Unlike ComposePathEffect, it independently displays both effects and then overlays them.
2. Code to Demonstrate Each Effect
Talking less and coding more is the best way to understand. Let's write some code to see the effects of these subclasses in action!
Run Effect:
Implementation Code:
We'll create our own View, where the moving effect of the lines is caused by increasing the phase and redrawing the view. PathEffectView.java:
/**
* Created by Jay on 2015/10/30 0030.
*/
public class PathEffectView extends View {
private Paint mPaint;
private Path mPath;
private float phase = 0;
private PathEffect[] effects = new PathEffect[7];
private int[] colors;
public PathEffectView(Context context) {
this(context, null);
}
public PathEffectView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// Initialize the paint
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // Anti-alias
mPaint.setStyle(Paint.Style.STROKE); // Stroke style
mPaint.setStrokeWidth(5); // Stroke width
mPath = new Path();
mPath.moveTo(0, 0);
for (int i = 1; i <= 15; i++) {
// Generate 15 points with random coordinates and connect them with a Path
mPath.lineTo(i * 40, (float) Math.random() * 100);
}
// Initialize 7 colors
colors = new int[] { Color.RED, Color.BLUE, Color.GREEN,
Color.YELLOW, Color.BLACK, Color.MAGENTA, Color.CYAN };
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
// Initialize path effects:
effects[0] = null; // No effect
effects[1] = new CornerPathEffect(10); // CornerPathEffect
effects[2] = new DiscretePathEffect(3.0f, 5.0f); // DiscretePathEffect
effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 }, phase); // DashPathEffect
Path p = new Path();
p.addRect(0, 0, 8, 8, Path.Direction.CCW);
effects[4] = new PathDashPathEffect(p, 12, phase,
PathDashPathEffect.Style.ROTATE); // PathDashPathEffect
effects[5] = new ComposePathEffect(effects[2], effects[4]); // ComposePathEffect
effects[6] = new SumPathEffect(effects[2], effects[4]); // SumPathEffect
// Move the canvas to (10,10) to start drawing
canvas.translate(10, 10);
// Draw the path with 7 different path effects and colors
for (int i = 0; i < effects.length; i++) {
mPaint.setPathEffect(effects[i]);
mPaint.setColor(colors[i]);
canvas.drawPath(mPath, mPaint);
canvas.translate(0, 60);
}
// Change the phase to create an animation effect
phase += 2;
invalidate();
}
}
The comments in the code are quite clear, so there's no need to elaborate further.
3. Download the Example Code:
Summary:
>
This section didn't cover anything particularly difficult. It simply introduced the effects of the six subclasses of PathEffect and how to apply them using the setPathEffect method on a Paint object. It's quite straightforward. That's all for now, thank you!
- 1.0 Android Basic Tutorial
- 1.0.1 2015年最新Android基础入门教程目录
- 1.1 Background and System Architecture Analysis
- 1.2 Development Environment Setup
- 1.2.1 Developing Android Apps with Eclipse + ADT + SDK
- 1.2.2 Developing Android Apps with Android Studio
- 1.3 Solving SDK Update Issues
- 1.4 Genymotion Emulator Installation
- 1.5.1 Git Tutorial: Basic Operations on Local Repositories
- 1.5.2 Using GitHub to Set Up a Remote Repository with Git
- 1.6 How to Use 9-Patch Images
- 1.7 Interface Prototype Design
- 1.8 Project-Related Analysis (Various Files, Resource Access)
- 1.9 Android App Signing and Packaging
- 1.11 Decompiling APK to Retrieve Code & Resources
- 2.1 Concepts of View and ViewGroup
- 2.2.1 LinearLayout (Linear Layout)
- 2.2.2 RelativeLayout (Relative Layout)
- 2.2.3 TableLayout (Table Layout)
- 2.2.4 FrameLayout (Frame Layout)
- 2.2.5 GridLayout (Grid Layout)
- 2.2.6 AbsoluteLayout (Absolute Layout)
- 2.3.1 Detailed Explanation of TextView (Text Field)
- 2.3.2 Detailed Explanation of EditText (Input Field)
- 2.3.3 Button and ImageButton
- 2.3.4 ImageView (Image View)
- 2.3.5 RadioButton (Radio Button) & Checkbox (Checkbox)
- 2.3.6 ToggleButton and Switch
- 2.3.7 ProgressBar (Progress Bar)
- 2.3.8 SeekBar (Drag Bar)
- 2.3.9 RatingBar (Star Rating Bar)
- 2.4.1 ScrollView (Scroll Bar)
- 2.4.2 Date & Time Components (Part 1)
- 2.4.3 Date & Time Components (Part 2)
- 2.4.4 Adapter Basics
- 2.4.5 Simple Usage of ListView
- 2.4.6 Optimization of BaseAdapter
- 2.4.7 Focus Issues with ListView
- 2.4.8 Solving Checkbox Misalignment in ListView
- 2.4.9 Data Update Issues in ListView
- 2.5.0 Building a Reusable Custom BaseAdapter
- 2.5.1 Implementing Multiple Item Layouts in ListView
- 2.5.2 Basic Usage of GridView (Grid View)
- 2.5.3 Basic Usage of Spinner (Dropdown List)
- 2.5.4 Basic Usage of AutoCompleteTextView (Auto-Complete Text Field)
- 2.5.5 Basic Usage of ExpandableListView (Expandable List)
- 2.5.6 Basic Usage of ViewFlipper (Flip View)
- 2.5.7 Basic Usage of Toast
- 2.5.8 Detailed Explanation of Notification (Status Bar Notification)
- 2.5.9 Detailed Explanation of AlertDialog (Dialog Box)
- 2.6.0 Basic Usage of Other Common Dialogs
- 2.6.1 Basic Usage of PopupWindow (Floating Box)
- 2.6.2 Menu (Menu)
- 2.6.3 Simple Usage of ViewPager
- 2.6.4 Simple Usage of DrawerLayout (Official Side Sliding Menu)
- 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 Changes (Configuration Class)
- 3.7 AsyncTask Asynchronous Tasks
- 3.8 Gestures (Gestures)
- 4.1.1 Introduction to Activity
- 4.1.2 Getting Started with Activity
- 4.1.3 Advanced Concepts in Activity
- 4.2.1 Introduction to Service
- 4.2.2 Advanced Topics in Service
- 4.2.3 Mastering Service
- 4.3.1 Introduction to BroadcastReceiver
- 4.3.2 In-Depth Analysis of BroadcastReceiver
- 4.4.1 Introduction to ContentProvider
- 4.4.2 Deeper Look into 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 Walkthrough — Bottom Navigation Bar Implementation (Method 1)
- 5.2.2 Fragment Example Walkthrough — Bottom Navigation Bar Implementation (Method 2)
- 5.2.3 Fragment Example Walkthrough — Bottom Navigation Bar Implementation (Method 3)
- 5.2.4 Fragment Example Walkthrough — Bottom Navigation Bar + ViewPager for Swiping Between Pages
5.2.5 Fragment Example Walkthrough — News (Shopping) App List Fragment Simple Implementation
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 Essentials and HTTP Protocol Study
7.1.2 Android HTTP Request Headers and Response Headers Study
7.5.3 Important Considerations for WebView in Android 4.4 and Later
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.14 Paint Enumerations/Constants and ShadowLayer Shadow Effects
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.3 Android Animation Collection — Property Animation - Introduction
8.4.4 Android Animation Collection — Property Animation - Further Exploration
11.0 "2015 Latest Android Basic Beginner Tutorial" Completion Celebration~
12.2 DrySister Viewing Girls Application (First Edition) — 2. Parsing Backend Data
12.5 DrySister View Girls App (Version 1) – 5. Code Review, Adjustment, and Logging Class Writing