Reprint please indicate source: http://blog.csdn.net/lmj623565791/article/details/40162163, this article from: "Zhang Hongyang's Blog"
Very long ago also had a HTML5 scraping card effect ~ ~ Last saw someone write Android scratch card effect ~ ~ so produced this blog ~ ~ ~ This kind of sample is also more than, we can Baidu look ~ just still through this sample, take us to explore. The Hidden Knowledge inside
1, Xfermode and Porterduff
Suppose you remember that before in the blog: the perfect realization of picture fillet and circular Introduction The rounding angle is also based on this principle.
First, let's take a look at the official examples. It's a great way to show the 16 mode effects:
Note: DST is drawn first. Then draw the SRC.
OK, look at this picture. Let me ask you a few questions:
Question 1, suppose I want to implement a circular picture. How to do it?
A: Draw our picture first, then draw a circle on it. The final result is a circular picture. Wait, how to generate, please look at the above srcin such a pattern;
The DST is drawn first. Then set the Dstin, and then draw the SRC; The final effect is to leave the intersection of the two and the part of DST; let's take our answers in here.
Draw the picture first, then set the Dstin. Then draw the circle. The final effect is to leave the intersection of the two and the part of the picture. Well, what is the intersection. Round, round content is what, picture, search karma, feel a little bit.
----
Wait, I still have a train of thought. Draw the circle first, then set the Srcin, and then draw our picture, or we can create our own circular image.
Let's take a look at:
Srcin final retained is still the intersection, but the display as after the drawing, that is, our pictures, search karma. It's also possible.
Question 2, suppose I want to realize the fillet picture, how to realize?
Answer: Rub. Read the answer above. You're not thinking yet.
Draw a circle and change it to draw a rounded rectangle. What else do you have to ask, the amount, ... The wood has.
Well. Turning the circle of question 1 into rounded corners, we have achieved our rounded picture in accordance with the same drawing process.
3. Does this have a yarn relationship with our scratch card?
A: How does it matter,,,, you draw the scratch layer first, then set the Dst_out. Then draw the line that touches the user's hand. The part of the user touching the scratch layer (the intersection section) is eliminated. It's just that the Scratch award layer was erased by US ~
This is not a scratch award. Wait, what about the prize?
The prize is nothing more than text, or pictures, drawn in advance. Then draw a scratch award layer on it. Set the Dst_out, then draw the user touch up. So disappear after you can see the prize behind ~ ~ ~, now there is an app called off what sister clothes. First draw the sister, then draw the clothes, then rub ~ ~ This and the scraping prize like, the amount, I said nothing.
Search karma, through the above 3 questions. Everyone should be clear about what the fillet is. Round, scratch card. In fact, the principle is so simple,
2. The realization of the simple artboard
Our scratch cards need to master the drawing, of course, there is no need for you to have an art talent, will be blind graffiti will be able to ~ ~
Let's start with one of our easy-to-follow artboards. In fact, you can draw a line on it, but 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;}}
The amount of code is relatively small. We made a mcanvas in memory and created a mbitmap. Then use our pre-set Mouterpaint to draw MPath on our mbitmap through Mcanvas;
What about the data inside the MPath? Is the ontouchevent inside constantly moveto. LineTo is good ~ ~ The code is still very arbitrary
Finally, note that we draw the memory on top of the Mbitmap, and then we pass the view of the canvas. To show our mbitmap. Hey. It's a bit of a double-cushioned sense of foot.
Well, now you can sweep on our board:
Here's a look at the layout file and how it works:
2. layout file and execution 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>
Execution effect:
See my vigorous font no, and so on after the program, I went to be a calligrapher ~
All right. After our simple artboard is finished. We started to think about the subject, step-by-step approach to our squeegee, and now we're ready to do it. First, draw a picture behind your back and draw a cover layer. Then our painting process is to erase the cover layer.
3, erase the first implementation
Given the opinion of a very many friends. I decided this picture with the 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 first principle of the article is finally used. When we draw the path, we need to set a pattern, here is dst_out, think of a little excitement ~
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);}
All right. It's over. In fact, the addition of a few lines of code, the end of our simple drawing board to the scratch card transformation;
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 very easy ~ Next is probably the good work
4, scraping the card intact
We are going to change the prize to font. Draws the font in the middle of the screen;
Then directly to the above example to draw a picture to draw the font can be, just one more 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);}
Here's how much money I've got:
Well, that's all for now. According to the same example, the combination of their own needs to change can be involved in the principle is believed to have been explained clearly; Almost forget that scratch cards generally have a feature when you hang up almost the same time. The coating will remove itself voluntarily. Below we try to join this feature.
5, statistics of the percentage of the area has been blown open
We can calculate it when we are action_up. First of all, let's instill the principle of calculation. Suppose you look at it attentively, we should know that all of our operations are basically in Mbitmap, and now we get all the pixels on the MBITMAP data. The area where the statistics are cleared (0 pixels cleared); Finally, with the total pixel number of our picture, we can get the percentage of our elimination.
Just, the calculation can be a time-consuming operation, the detailed speed is related to the image size, 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++;}}} /** * per cent of the basis. Do some operations */if (Wipearea > 0 && totalarea > 0) {int percent = (int) (Wipearea * 100/totalarea); LOG.E ("TAG", Percent + ""); if (Percent >) {iscomplete = True;postinvalidate ();}}};
With this task, we can invoke it when action_up:
Case MotionEvent.ACTION_UP:new Thread (mrunnable). Start ();
Note that the task ends with a iscomplete set to true. When True. We show the scratch zone 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.
The following is before the demo. I did some simple landscaping, detailed everyone will be able to see the source code.
This is the end of our scratch card production, and assuming that you want to be intact, you can set a lot of constants into variables, adding external set methods. Or extract their own definition of properties, in the layout file definition can be ~ ~ ~
One thing needs to be explained, for our scratch card case. Our layout file assumes that the width height is set to wrap_content. will also occupy the screen, mainly because I think the scratch card view is not required wrap_content, but suppose you want to support wrp_content, can refer to the Android own definition view (a).
Source code 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 the boring text, please poke (first record). Looking forward to your support):
1, High imitation 5.2.1 main interface and message alert
2, high imitation QQ5.0 sideways slip
Android self-defined controls achieve scratch card effect is it just a scratch card?