Reprint please indicate source: http://blog.csdn.net/lmj623565791/article/details/40162163, this article from: "Zhang Hongyang's Blog"
A long time ago also had a HTML5 scraping card effect ~ ~ Last saw someone write Android scratch card effect ~ ~ so produced this blog ~ ~ ~ This kind of example is also more, we can Baidu to see ~ but still through this example, take us to explore, the hidden knowledge of the inside ~
1, Xfermode and Porterduff
If you remember, once in the blog: the perfect realization of the picture fillet and circular simple introduction of the round angle is also based on this principle.
First, let's take a look at the official example, which shows the effects of the 16 mode in a good way:
Note: First draw the DST, then draw the SRC.
Well, looking at this picture, let me ask you a few questions:
Question 1, if I want to achieve a circular picture, how to achieve?
A: First draw our picture, then draw a circle on it, the final result is a circular picture, and so on, how to generate, see the above srcin this mode;
Draw the DST first, then set the Dstin, and then draw the SRC; The final effect is to leave the intersection of the two and the DST part; Let's take our answer in.
Draw the picture first, then set the Dstin, and then draw the circle; the final effect is to leave the intersection of the two and the part of the picture; Well, what's the intersection, the circle, what the circle is, what the picture is, a little bit of a feeling.
----
And so on, I have a train of thought, draw the circle first, then set the Srcin, then draw our picture, also can produce our circle picture. Let's take a look at:
Srcin finally retained is still the intersection, but displayed as after the drawing, that is, our pictures, search karma, so also can.
Question 2, if I want to achieve a rounded picture, how to achieve?
A: Wipe, read the above answer, you have no idea. Draw a circle and change it to draw a rounded rectangle. What else do you ask, the amount,,, the wood has.
Well, change the circle of question 1 into rounded corners, and follow the same drawing process to achieve our rounded picture.
3. Does this have a yarn relationship with our scratch card?
A: How does it not matter,,, you first draw the scratch layer, and then set up the Dst_out, and then the user hand to touch the line to draw up, the user touch to the scratch layer (intersection part) display is the user touch of the line, then we this line if it is transparent, it is said that the scratch layer was erased by US ~
This is not a scratch award. Wait, what about the prize?
The prize is nothing more than text, or a picture, draw it ahead of time, then draw a scratch layer on it, set the Dst_out, and then draw the user touch, and then you can see the prize behind it! ~ ~ Right, now there is an app called off what Sister clothes, first draw sister, then draw clothes, then wipe ~ ~ It doesn't look like a scratch award, I didn't say anything.
Search karma, after the above 3 questions, we should understand, what rounded corners, round, scraping card, in fact, the principle is so simple,,,
2. The realization of the simple artboard
Our scratch card needs to master the drawing, of course, here does not require you have art talent, will be blind graffiti on it ~ ~
Below the beginning of one of our simple drawing board, in fact, you can draw some lines, of course, you can also sign a name, our view is called Guaguaka:
1. Preliminary Guaguaka
Package Com.zhy.view;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmap.config;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.path;import Android.util.attributeset;import Android.view.motionevent;import Android.view.view;public class Guaguaka extends view{/** * Draw the paint of the line, that is, the user fingers draw path */ Private Paint Moutterpaint = new paint ();/** * Records User-drawn path */private path MPath = new Path ();/** * Canvas */private created in memory Canvas mcanvas;/** * Mcanvas draw content on it */private Bitmap mbitmap;private int mlastx;private int mlasty;public Guaguaka (Contex T context) {This (context, null);} Public Guaguaka (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public Guaguaka (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, defstyle); init ();} private void Init () {MPath = new Path ();} @Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (WidthmeaSurespec, heightmeasurespec); int width = getmeasuredwidth (); int height = getmeasuredheight ();//Initialize BITMAPMBITMAP = Bitmap.createbitmap (width, height, config.argb_8888), Mcanvas = new Canvas (MBITMAP);//Set Brush Moutterpaint.setcolor ( color.red); Moutterpaint.setantialias (true); Moutterpaint.setdither (true); Moutterpaint.setstyle ( Paint.Style.STROKE); Moutterpaint.setstrokejoin (Paint.Join.ROUND); Fillet Moutterpaint.setstrokecap (Paint.Cap.ROUND); Fillet//Set brush width moutterpaint.setstrokewidth (20);} @Overrideprotected void OnDraw (canvas canvas) {drawpath (); Canvas.drawbitmap (mbitmap, 0, 0, null);} /** * Draw line */private void DrawPath () {Mcanvas.drawpath (MPath, moutterpaint);} @Overridepublic boolean ontouchevent (Motionevent event) {int action = event.getaction (); int x = (int) event.getx (); int y = (int) event.gety (); switch (action) {case MotionEvent.ACTION_DOWN:mLastX = X;mlasty = Y;mpath.moveto (Mlastx, mlasty); Break;case MotionEvent.ACTION_MOVE:int dx = math.abs (x-mlastx); int dy = Math.Abs (y-mlasty); if (dx >3 | | Dy > 3) mpath.lineto (x, y); mlastx = X;mlasty = Y;break;} Invalidate (); return true;}}
With less code, we made a mcanvas in memory, created a mbitmap, and then plotted mbitmap on our mpath by Mcanvas using our pre-set mouterpaint;
What about the data inside the MPath? is ontouchevent inside constantly moveto,lineto is good ~ ~ code is still very casual
Finally, notice that we draw the mbitmap above the memory, and then we show our mbitmap through the canvas of the view. Hey, how a bit of a double cushion sense feet.
Well, now you can take it out on our board:
Here's a look at the layout file and how it works:
2. layout file and Operation effect
Layout file:
<relativelayout 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 " > <com.zhy.view.guaguaka android:layout_width= "match_parent" android:layout_height= "Match_ Parent "/></relativelayout>
Operating effect:
See my vigorous font no, and so on after the program, I went to be a calligrapher ~
Well, when we're done with the simple artboard, we start thinking about the point, step-by-step approach to our scraper, and now we're ready to do it, first draw a picture behind the back, then draw a cover layer, and then we paint the process of erasing the cover layer.
3, erase the first implementation
In view of the views of many friends, I decided this picture with landscape, away from xxx, thanks to the pictures provided by seven ~
1. Draw the covering layer
In fact, the cover layer is a color:
@Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec, HEIGHTMEASURESPEC); int width = getmeasuredwidth (); int height = getmeasuredheight ();//Initialize BITMAPMBITMAP = Bitmap.createbitmap (width, height, config.argb_8888); Mcanvas = new Canvas (MBITMAP); Setupoutpaint ();// Draw this change to Mcanvas.drawcolor (Color.parsecolor ("#c0c0c0"));}
And the code above the last line, in addition to our paint settings extracted out ~
2, DrawPath
The article at the beginning of the principle is finally used, we draw the path, we need to set a pattern, here is dst_out, think a little excited ~
private void DrawPath () {Moutterpaint.setxfermode (new Porterduffxfermode (PorterDuff.Mode.DST_OUT)); Mcanvas.drawpath (MPath, moutterpaint);}
3, OnDraw
OnDraw to make a little change inside.
@Overrideprotected void OnDraw (canvas canvas) {canvas.drawbitmap (mbackbitmap, 0, 0, NULL);d Rawpath (); Canvas.drawbitmap (mbitmap, 0, 0, null);}
Well, to this completion, in fact, added a few lines of code, the completion of our simple board to scratch the change of the card;
Here's how it works:
There is no way to see the morning clouds of the feeling ~ ~
To this the principle of our scratch card, as well as the initial implementation of the end of ~ ~ or is very simple ~ Next is the follow-up of the improvement work
4. Perfection of scraping and scraping card
We are going to change the prize to font and draw the font in the middle of the screen;
Then directly to the above example to draw a picture to draw a font on the line, but more than a drawing font brush settings:
Code with Changes:
Private Paint Mbackpint = new paint ();p rivate rect mtextbound = new rect ();p rivate String mText = "500,0000,000";/** * Initialization Canvas drawing brush */private void Setupbackpaint () {Mbackpint.setstyle (Style.fill); Mbackpint.settextscalex (2f); Mbackpint.setcolor (Color.dkgray); mbackpint.settextsize; Mbackpint.gettextbounds (mText, 0, Mtext.length (), Mtextbound);} @Overrideprotected void OnDraw (canvas canvas) {//Canvas.drawbitmap (mbackbitmap, 0, 0, NULL);//Draw award Canvas.drawtext ( MText, GetWidth ()/2-mtextbound.width ()/2,getheight ()/2 + mtextbound.height ()/2, Mbackpint);d Rawpath (); Canvas.dra Wbitmap (mbitmap, 0, 0, null);}
Let's see how much money I have:
Well, to this has been fully realized, we follow the example, combined with their own needs to modify can, the principle involved in the theory has been explained clearly; Yes, almost forgot, scratch cards generally have a function, when you hang the same time, the coating will be automatically cleared, below we try to add the feature.
5, statistics of the percentage of the area has been blown open
We action_up in the time of the calculation, first of all, we have to instill the principle of calculation, if you look at the heart, we should know that all of our operations are basically in the mbitmap, now we get mbitmap on all the pixel data, The area where the statistics are cleared (0 pixels cleared); At last, we can divide the total pixel number of our picture into a percentage of our elimination.
However, the calculation can be a time-consuming operation, and the speed is related to the size of the image, so we decided to use the asynchronous way to calculate:
/** * Statistics Erase area task */private Runnable mrunnable = new Runnable () {private int[] mpixels; @Overridepublic void Run () {int w = GETW Idth (); int h = getheight (); float Wipearea = 0;float Totalarea = w * h; Bitmap Bitmap = Mbitmap;mpixels = new Int[w * h];/** * Get all the pixel information */bitmap.getpixels (mpixels, 0, W, 0, 0, W, h);/** * Traverse statistical wipe Except for the area */for (int i = 0; i < W; i++) {for (int j = 0; J < H; j + +) {int index = i + J * W;IF (mpixels[index] = = 0) {wipear ea++;}}} /** * Depending on the percentage, do some operations */if (Wipearea > 0 && totalarea > 0) {int percent = (int) (Wipearea * 100/totalarea); L OG.E ("TAG", Percent + ""); if (Percent >) {iscomplete = True;postinvalidate ();}}};
With this task, we'll call when we're action_up:
Case MotionEvent.ACTION_UP:new Thread (mrunnable). Start ();
Note that a iscomplete is set to True when the task is finished, and when True, we show the scratch area directly
@Overrideprotected void OnDraw (canvas canvas) {drawbacktext (canvas), if (!iscomplete) {DrawPath (); Canvas.drawbitmap ( Mbitmap, 0, 0, null);}}
The calculation for this scratch zone is over.
Below in the demonstration before, I did some simple beautification, the concrete everybody then sees the source code to be possible.
To this end of our scraping card production, in addition, if you want to perfect, you can put a lot of constant variables, add external set method, or extract custom properties, in the layout file definition can be ~ ~ ~
One thing to explain, for our scratch card case, our layout file if the width is set to Wrap_content, will also occupy the screen, mainly because I think the scratch card view is not necessary wrap_content, but if you want to support wrp_content, You can refer to Android Custom view (one).
SOURCE Click to download
---------------------------------------------------------------------------------------------------------
I built a QQ group, convenient for everyone to communicate. Group number:55032675
----------------------------------------------------------------------------------------------------------
Bo Master part of the video has been online, if you do not like boring text, please poke (first record, look forward to your support):
1, High imitation 5.2.1 main interface and message alert
2, high imitation QQ5.0 slide
Android custom controls achieve scratch card effect is it just a scratch card?