Custom Views are divided into inherited from View and ViewGroup. Inheriting ViewGroup is compared to inheriting View
- ViewGroup multiple dispatchTouchEvent and onInterceptTouchEvent (event intercept) methods on event distribution
- In inheritance, ViewGroup needs to focus on onmeasure and onLayout (control position, etc.), while inheriting View is focused on onDrow (draw)
In this article, we will simply implement a custom signature class, which moves through the screen by touching the fingers, and displays the path of the fingers sliding through. First create the SignatureView and inherit from the View:
class SignatureView constructor(context: Context?, attrs: AttributeSet? = null) : View(context, attrs, 0) { private lateinit var paint: Paint private var mWidth = 0 // Parent class width private var mHeight = 0//Preparent class height override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { (widthMeasureSpec, heightMeasureSpec) mWidth = (widthMeasureSpec) mHeight = (heightMeasureSpec) paint = Paint() //Set anti-aliasing = true //Set the signature stroke style = setMeasuredDimension(mWidth, mHeight) } override fun onDraw(canvas: Canvas) { (canvas) ...... } }
All you need to do next is actually two tasks: touch event processing and drawing paths. Drawing needs to be done in onDraw through the initial brush paint and canvas, so the touch event needs to be overridden and listened to onTouchEvent method:
override fun onTouchEvent(event: MotionEvent): Boolean { (event) }
It should be noted here that since the signature is recorded in real time, we need to record the sliding point, connect it into a line, and then draw the line through a pain. The drawing process is to press the movement operation, so in the ACTION_MOVE process, we need to draw lines in real time. The brush completion is the lifting action, so when ACTION_UP we need to draw all previous points on the canvas. Here, the points that fingers move by a collection of points are collected and drawn by the user's brush.
//Collect points drawn by usersprivate var allPoints: MutableList<Point> = ArrayList() val p = Point((), ()) when () { MotionEvent.ACTION_DOWN -> { //The user presses to indicate that the save point is restarted () (p) } MotionEvent.ACTION_UP -> { postInvalidate() //Repaint the image } MotionEvent.ACTION_MOVE -> { (p) postInvalidate() //Child thread can be refreshed } }
Next is to draw in onDrow(), by:
val first = allPoints[0] //The first pointval last = allPoints[-1] //The last point((),(),(),(),paint)
It's basically over here, but we still need the function of withdrawing and clearing. At this time, you need to think about it. If you follow the press -> Move -> Lift as a stroke, then if you withdraw, you need to clear all points in the process. At this time, we can imagine this process as a line, record the beginning of the line when pressed, lift the end of the line, and then store the line in a collection, and delete the data if it needs to be withdrawn.
// Used for display after drawing the picture. When lifting, add data from all points in allPointsprivate var allList: MutableList<List<Point>> = ArrayList() // Used for display during scribing. When the collection allList is stored, all data in this collection is cleared.private var allPoints: MutableList<Point> = ArrayList() override fun onTouchEvent(event: MotionEvent): Boolean { (event) val p = Point((), ()) when () { MotionEvent.ACTION_DOWN -> { //The user presses to indicate that the save point is restarted allPoints = ArrayList() (p) } MotionEvent.ACTION_UP -> { //User releases (allPoints) allPoints = ArrayList() //After adding a collection, clear the subset postInvalidate() //Repaint the image } MotionEvent.ACTION_MOVE -> { (p) postInvalidate() //Child thread can be refreshed } } return true } //Previous step (clear this painting)fun clearLatestData() { if ( > 0) { ( - 1) ( - 1) } postInvalidate() }
Clearing is easier. Just clear all the lines in the collection, but don't forget to refresh the view:
//Reset (clear all paintings)fun clearAllData() { () postInvalidate() }
Summarize
In fact, it is not difficult to do the whole set. The main thing involved is custom View inherited from the View method. From easy to difficult, first realize the most basic function, collect the data we need through different actions of touch events, and then draw the collected lines in conjunction with the onDrow method. Don't forget to refresh the view. In fact, lines with multiple colors and styles can be collected through containers and set brush attributes for different lines to meet the requirements. This article ends with this article and I hope it will be helpful to everyone. In the next article, we will talk about the issue of restricting the brush area of the special shape area.
The above is the detailed content of Android customization of the Graffiti Tool for the angle of the restricted area and the graphical angle of the restricted area. For more information about the Android restricted area and the graffiti tool for the restricted area, please pay attention to my other related articles!