The realization of the water ripple loading of Android custom control

Source: Internet
Author: User

NN, demand or not down, the whole day more, the whole of a loading box, it seems that I am the loading box is the sentiment has a single clock, good, not many BB, first:

  

Well, it is such a thing, compared to the first two, there is a bit of technical content, but in fact, it is not difficult, the reason is to do more than a day, because it is also special to tread a pit, pit me an afternoon of time, hurt, as to what is the pit, the following again;

Well, to complete this before the necessary knowledge reserves, quadratic Bezier curve, also to read some articles on the internet, and said to Sanche Besel curve knowledge, in fact, I feel that there is no need, the second order is enough, the following attached a link, read it will know the Bezier curve is a

What stuff: http://blog.csdn.net/cdnight/article/details/48468653

Now that you know the Bezier curve, you can begin to say it.

To complete this loading pattern, I think there are two main difficulties (do not know how to achieve before), one is how to achieve the water ripple effect, one is how to combine the background and water ripple effectively (there is a pit, please note)!

First of all, the water ripple effect, well, is actually two sets of positive selection curve has been doing translational motion (the reason is difficult, because it is not exposed before, I was a face-_-!! );

Then the combination of the words will be used to paint the Setxfermode () interface, in which you specify a Porterdufffermode class enumeration object, specifically, here is also attached a link: http://blog.csdn.net/zidan_2011 /article/details/21518351

Well, how exactly, on the code to analyze it!

 

public class Waveloading extends View {
Private Paint Wavepaint;
Private Bitmap Wavebitmap;
Private Canvas Wavecanvas; Painting the water ripple related stuff
Private Paint Cirpaint;
Private Bitmap Cirbitmap;
Private Canvas Circanvas; Painting Background Garden related stuff
Private Paint Mpaint; The brush of the canvas canvas
Private Bitmap Midbitmap;
Private Canvas Midcanvas;
Private Paint Midpaint; Intermediate canvas for combining background and water ripples
private int viewwidth; The width of the control
private int viewheight; Control's high
Private Path MPath; The path used to draw the water ripple
private int offset; The offset of the ripple effect of water ripples
private int progress = 0; Progress bar
Private Android.os.Handler Mhander = new Handler () {
@Override
public void Handlemessage (Message msg) {
Super.handlemessage (msg);
Invalidate ();
}
};

Public waveloading (Context context) {
This (context, NULL);
}

Public waveloading (context context, AttributeSet Attrs) {
This (context, attrs, 0);
}

Public waveloading (context context, AttributeSet attrs, int defstyleattr) {
Super (context, attrs, defstyleattr);
Initsetting ();
}

private void initsetting () {
Wavepaint = new Paint ();
Wavepaint.setcolor (Color.parsecolor ("#0404FF"));
Wavepaint.setantialias (TRUE);
Wavepaint.setstyle (Paint.Style.FILL);
Cirpaint = new Paint ();
Cirpaint.setcolor (Color.parsecolor ("#88888888"));
Cirpaint.setantialias (TRUE);
Mpaint = new Paint ();
Mpaint.setstyle (Paint.Style.FILL);
Midpaint = new Paint ();
Midpaint.setstyle (Paint.Style.FILL);
}

@Override
protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
Viewwidth = Measurespec.getsize (Widthmeasurespec);
Viewheight = Measurespec.getsize (Heightmeasurespec);
offset =-viewwidth;
Initbitmap ();
Super.onmeasure (Widthmeasurespec, Heightmeasurespec);
}

private void Initbitmap () {
if (Wavebitmap = = null) {
Wavebitmap = Bitmap.createbitmap (Viewwidth, Viewheight, Bitmap.Config.ARGB_8888);
Wavecanvas = new Canvas (WAVEBITMAP);
}
if (Cirbitmap = = null) {
Cirbitmap = Bitmap.createbitmap (Viewwidth, Viewheight, Bitmap.Config.ARGB_8888);
Circanvas = new Canvas (CIRBITMAP);
}
if (Midbitmap = = null) {
Midbitmap = Bitmap.createbitmap (Viewwidth, Viewheight, Bitmap.Config.ARGB_8888);
Midcanvas = new Canvas (MIDBITMAP);
}
}


@Override
protected void OnDraw (canvas canvas) {
Circanvas.drawcircle (VIEWWIDTH/2, VIEWHEIGHT/2, Cirpaint);
DRAWSRC ();
Midcanvas.drawbitmap (cirbitmap, 0, 0, midpaint);
Midpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.SRC_ATOP));
Midcanvas.drawbitmap (wavebitmap, 0, 0, midpaint);
String percent = Progress <= 300? PROGRESS/3 + "%": "100%";
Mpaint.settextsize (50);
Mpaint.settextalign (Paint.Align.CENTER);
Canvas.drawtext (Percent, (viewwidth)/2, (Viewheight)/2, mpaint);

Canvas.drawbitmap (midbitmap, 0, 0, mpaint);
Super.ondraw (canvas);
}

private void Drawsrc () {
Wavebitmap.erasecolor (Color.parsecolor ("#00000000"));
MPath = new Path ();
Wavepaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.XOR));
for (int i = 0; i < 4; i++) {
if (i% 2 = = 0) {
Mpath.reset ();
Mpath.moveto (offset + i * VIEWWIDTH/2, viewheight-progress);
Mpath.quadto (offset + (1 + 2 * i) * VIEWWIDTH/4, viewheight-progress-40,
Offset + (1 + i) * viewwidth/2, viewheight-progress);
Wavecanvas.drawpath (MPath, wavepaint);
} else {
Mpath.reset ();
Mpath.moveto (offset + i * VIEWWIDTH/2, viewheight-progress);
Mpath.quadto (offset + (1 + 2 * i) * VIEWWIDTH/4, viewheight-progress + 40,
Offset + (1 + i) * viewwidth/2, viewheight-progress);
Wavecanvas.drawpath (MPath, wavepaint);
}
}
Mpath.reset ();
Wavecanvas.drawrect (0, Viewheight-progress, Viewwidth, Viewheight, Wavepaint);
}

public void startloading () {
Timer timer = new timer ();
TimerTask task = new TimerTask () {
@Override
public void Run () {
progress++;
Offset + = 3;
if (offset = = 0) offset =-viewwidth;
if (progress = = Viewheight +) Progress = 0;
Mhander.obtainmessage (1). Sendtotarget ();
}
};
Timer.schedule (Task, 10, 10);
}
}

Onmeasure and those initialization methods are no longer analyzed, directly focused:
1. Realization of water Ripple code
private void Drawsrc () {
Wavebitmap.erasecolor (Color.parsecolor ("#00000000"));
MPath = new Path ();
Wavepaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.XOR));
for (int i = 0; i < 4; i++) {
if (i% 2 = = 0) {
Mpath.reset ();
Mpath.moveto (offset + i * VIEWWIDTH/2, viewheight-progress);
Mpath.quadto (offset + (1 + 2 * i) * VIEWWIDTH/4, viewheight-progress-40,
Offset + (1 + i) * viewwidth/2, viewheight-progress);
Wavecanvas.drawpath (MPath, wavepaint);
} else {
Mpath.reset ();
Mpath.moveto (offset + i * VIEWWIDTH/2, viewheight-progress);
Mpath.quadto (offset + (1 + 2 * i) * VIEWWIDTH/4, viewheight-progress + 40,
Offset + (1 + i) * viewwidth/2, viewheight-progress);
Wavecanvas.drawpath (MPath, wavepaint);
}
}
Mpath.reset ();
Wavecanvas.drawrect (0, Viewheight-progress, Viewwidth, Viewheight, Wavepaint);
}
After the implementation of the effect is basically like this

  

As can be seen, is a very obvious sine wave, the overstating is by changing the progress, the fluctuation is achieved by changing the offset, the specific code in the Startloading () method, where the use of Porterduffxfermode mode.xor or, According to the name, it is shown that the part is not intersected, and the purpose is to remove the water ripple in the SAG;

2. Combination of water ripples and prototype backgrounds

Here is the mode.src_atop in Porterduffxfermode, which shows the portion of the layer below which intersects the layer below (the Blue water), in fact, you will be surprised, you can draw it, directly with the canvas on the control of the painting is not good, Why do you want to use a midcanvas for superfluous?

This has to say I said that the pit, you directly on the canvas above the words, set the Porterduffxfermode does not work, or, the role is completely chaotic (I use, there is no law found at all, there is a friend who knows can leave a message below me), So you have to use a middle of the canvas, the water ripple and the circle to add to the canvas again, summed up is that in OnDraw (canvas canvas) on the canvas of the words bitmap, it is best to directly related to the bitmap only one;

  

Today's sharing is here, recording life, common progress!

The realization of the water ripple loading of Android custom control

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.