For the most fire before the set five blessing, and five blessings in addition to add 10 friends, the most direct way is to pay treasure of a swish. So what is the specific way to achieve a thump? Below we will introduce each of these kinds of ideas of the realization process.
1. Customize view Implementation a swish
So this implementation requires mastering almost every method of canvas and paint. It requires a very high knowledge of the programmer's expertise.
The advantages of this approach are:
- ㈠ This is the most complex implementation, but its highest compatibility, its support for all Android devices.
- ㈡ it requires little memory and hardly consumes any memory.
Let's take a look at how it works:
public class Xiuyixiuview extends View {/*** * Center picture Brush */Private Paint Paint;
/*** * Water Wave circle brush/private Paint circlepaint;
/*** * Create canvas with Bitmap * * Private Bitmap Bitmap;
/*** * Center Picture * * Private Bitmap imagebit;
/*** * Canvas/private Canvas Canvas;
/*** * Screen of the wide * * * private int screenwidth;
/*** * Screen High * * private int screenheight;
/*** * Picture Right corner coordinate * * Pointlefttop private point;
/*** * Picture Right lower corner coordinates * * Pointrightbottom private point;
/*** * Record Circle * * Private list<lyjcircle> lyjcirclelist;
/*** * Mark whether the button is pressed and whether the source is diffused/private Boolean isspread=false;
/*** * Default does not press when the circle * * Private lyjcircle defaultcircle;
Public Xiuyixiuview (context, AttributeSet attrs) {Super (context, attrs);
This.lyjcirclelist=new arraylist<> ();
Screenwidth=lyjutils.getscreenwidth (activity);
Screenheight=lyjutils.getscreenheight (activity); Bitmap = Bitmap.createbitmap (ScreenWidth, ScreenHeight, Bitmap.Config.ARGB_8888);
Sets the bitmap's width high canvas = new canvas ();
Canvas.setbitmap (bitmap);
Paint=new paint (Paint.dither_flag);
Paint.setantialias (TRUE);
Circlepaint=new Paint (Paint.dither_flag);
Circlepaint.setantialias (TRUE);
imagebit= Bitmapfactory.decoderesource (Getresources (), r.drawable.bwa_homepage_yuyin);
Pointlefttop=new Point ((SCREENWIDTH/2)-(Imagebit.getwidth ()/2), (SCREENHEIGHT/2)-(Imagebit.getheight ()/2));
Pointrightbottom=new Point (Pointlefttop.x+imagebit.getwidth (), Pointlefttop.y+imagebit.getheight ());
Canvas.drawbitmap (Imagebit,pointlefttop.x,pointlefttop.y,paint); Take the color on the picture Palette.generateasync (Imagebit, New Palette.paletteasynclistener () {@Override public void ongenerated P Alette palette) {Palette.swatch swatch1 = Palette.getvibrantswatch ();//Vibrant color swatch Circlepaint.setcolor (swatch1.getr
GB ());
Circlepaint.setstyle (Paint.Style.STROKE);
Circlepaint.setstrokewidth (10);
Circlepaint.setalpha (100); Paint.setshadowlayer (0, 0, Swatch1.getrgb ());Set shadow effect int[] mcolors = new int[] {//Render color Color.transparent,swatch1.getrgb ()};
Range, where you can fine-tune, achieve the gradient you want float[] mpositions = new float[] {0f, 0.1f};
Shader shader=new radialgradient (Screenwidth/2,screenheight/2,imagebit.getwidth ()/2 + 10,mcolors, mPositions,
Shader.TileMode.MIRROR);
Circlepaint.setshader (shader);
Defaultcircle=new lyjcircle (SCREENWIDTH/2, SCREENHEIGHT/2, Imagebit.getwidth ()/2 + 10);
Clearscreenanddrawlist ();
Message message = Handler.obtainmessage (1); handler.sendmessagedelayed (message, 1000);
Send Message}}); @Override public boolean ontouchevent (Motionevent event) {switch (event.getaction ()) {case Motionevent.action_d
Own:break;
Case MotionEvent.ACTION_MOVE:break; Case motionevent.action_up:isspread=true;//whether to press the picture Lyjcirclelist.add (New Lyjcircle (SCREENWIDTH/2, ScreenHeight/
2, Imagebit.getwidth ()/2 + 10));
Clearscreenanddrawlist (); InvalidaTe ();
Break
Default:break;
return true;
Private Handler Handler = new Handler () {public void Handlemessage (msg) {switch (msg.what) {Case 1:
Regular Update interface clearscreenanddrawlist ();
Invalidate ();
Message message = Handler.obtainmessage (1);
handler.sendmessagedelayed (message, 200);
Super.handlemessage (msg);
}
}; /** * Clear all the circles on the screen, then draw the circle inside the collection/private void Clearscreenanddrawlist () {Canvas.drawcolor (color.transparent, Porterd Uff.
Mode.clear);
Determine if the picture is pressed, and the outer ring execution is not done.
if (!isspread) {circlepaint.setmaskfilter (null); Canvas.drawcircle (Defaultcircle.getroundx (), Defaultcircle.getroundy (), Defaultcircle.getradiuloop (), CirclePaint //Draw line}else{for (lyjcircle lyjcircle:lyjcirclelist) {if (Lyjcircle.getspreadradiu () ==0) {}else if (lyjci Rcle.getspreadradiu () > (Lyjcircle.getradiu () +99) {//If the circle diffusion radius is greater than the picture radius of +99, then set the Edge blur, which is the effect of fading out CIRCLEPAINT.SETMASKFI Lter (New Blurmaskfilter (5, BlurmaskFilter.Blur.OUTER)); Canvas.drawcircle (Lyjcircle.getroundx (), Lyjcircle.getroundy (), Lyjcircle.getspreadradiu (), circlePaint);//Draw line}
else{//Is circlepaint.setmaskfilter (null) according to normal ring rendering;
Canvas.drawcircle (Lyjcircle.getroundx (), Lyjcircle.getroundy (), Lyjcircle.getspreadradiu (), circlePaint);//Draw Line}}
} canvas.drawbitmap (Imagebit,pointlefttop.x,pointlefttop.y,paint); The circle for freeing hours for (int i=0;i<lyjcirclelist.size (); i++) {if (Lyjcirclelist.get (i). Getspreadradiu () ==0) {Lyjcirclelis
T.remove (i);
If you do not click on the image to launch the circle, then restore the default zoom.
if (Lyjcirclelist.size () <=0) {isspread=false;
} @Override protected void OnDraw (Canvas Canvas) {canvas.drawbitmap (bitmap, 0, 0, NULL);
}
}
Circle class:
Package Com.example.liyuanjing.model;
/** * Created by liyuanjing on 2016/2/3. * * Public class Lyjcircle {private int roundx;//Circle Center point x Coordinate private int roundy;//Circle Center point y coordinate private int radiu;//circle RADIUS Private int currentradiu;//current Radiu private int lastradiu;//history Radiu Private int spreadradiu;//acceleration radius private int[] Speed=new int[] {6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6};//radius expands speed.
Here for the uniform private int speedlast=0;//record history value public lyjcircle (int roundx,int roundy,int radiu) {this.roundx=roundx;
This.roundy=roundy;
This.radiu=radiu;
This.spreadradiu=radiu;
This.currentradiu=this.radiu;
This.lastradiu=this.currentradiu;
//Get the RADIUS public int Getradiu () {return radiu;
The public void Setradiu (int radiu) {This.radiu = Radiu;
//Get acceleration radius public int Getspreadradiu () {if (speedlast>=speed.length) {return 0;
} Spreadradiu+=speed[speedlast];
++speedlast;
return Spreadradiu; //Get loop scaling radius public int Getradiuloop () {if (Currentradiu==lastradiu) {++currentraDiu;
}else if (Currentradiu>lastradiu) {if (currentradiu> (radiu+20)) {Currentradiu=19+radiu;
Lastradiu=20+radiu;
}else{Lastradiu=currentradiu;
currentradiu+=5;
}}else{if (currentradiu< (radiu+9)) {Currentradiu=10+radiu;
Lastradiu=9+radiu;
}else{Lastradiu=currentradiu;
currentradiu-=5;
} return Currentradiu;
public int getroundx () {return roundx;
public int Getroundy () {return roundy;
}
}
You can modify the following two places to produce visually true ripple effects:
① Alipay's background picture is pale red, foil the red ripple. Of course, you can also set the canvas to be transparent and light red.
② it as a fill circle rendering, not my border rendering effect, you can Circlepaint.setstyle (Paint.Style.STROKE); Change to Paint.Style.FILL. Then, fine-tune the shader mpositions to implement the annular fill gradient. You might think, you see pay Bao Xiu a circle when the ring is open, the inner circle has a ripple also like outside, in fact that is the ring gradient, when your circle becomes larger, the range of its gradient will become larger, naturally you see the color around the spread of signs.
2. Property animation to achieve a swish
It only needs to master the basic attributes of animation, in addition to a bit of thread-related knowledge.
Let's take a look at the implementation steps below:
㈠ Custom view to implement a circle, the code is as follows:
public class Lyjcircleview extends View {private Bitmap Bitmap;
Private Paint Paint;
Private Canvas Canvas;
private int screenwidth;
private int screenheight;
Private Boolean isspreadflag=false;//tag whether the launch completes public boolean Isspreadflag () {return isspreadflag;
} public void Setisspreadflag (Boolean isspreadflag) {this.isspreadflag = Isspreadflag;
} public Lyjcircleview (context context,int width,int Height,int statusheight) {super (context);
Screenwidth= lyjutils.getscreenwidth (activity);
Screenheight=lyjutils.getscreenheight (activity); Bitmap = Bitmap.createbitmap (ScreenWidth, ScreenHeight, Bitmap.Config.ARGB_8888);
Sets the bitmap's width high canvas = new canvas ();
Canvas.setbitmap (bitmap);
Paint=new paint (Paint.dither_flag);
Paint.setantialias (TRUE);
Paint.setcolor (color.red);
Paint.setstyle (Paint.Style.STROKE);
Paint.setstrokewidth (5);
Paint.setalpha (100);
Paint.setshadowlayer (0, 0, color.red); int[] mcolors = new int[] {Color.
Transparent,color.red};
float[] mpositions = new float[] {0f, 0.1f}; Shader shader=new radialgradient (SCREENWIDTH/2,SCREENHEIGHT/2,WIDTH/2 + 10,mcolors, mpositions, Shader.TileMode.
MIRROR);
Paint.setshader (shader);
Canvas.drawcircle (SCREENWIDTH/2, (screenheight-statusheight)/2, WIDTH/2 + paint);
Invalidate ();
} @Override protected void OnDraw (Canvas Canvas) {canvas.drawbitmap (bitmap,0,0,null);
}
}
The code is similar to the above and is not commented on.
㈡ to achieve activity can
public class Xiuyixiuactivity extends Appcompatactivity {private ImageButton Mimagebutton;
Private Lyjcircleview Lyjcircleview;
Private Relativelayout relativelayout;
Private list<lyjcircleview> lyjcircleviewlist;
private int statusbarheight;
Private animator Anim;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.xiuyixiu_activity_main);
this.mimagebutton= (ImageButton) Findviewbyid (R.id.xiuyixiu_imagebutton);
this.relativelayout= (relativelayout) Findviewbyid (r.id.xiuyixiu_relativelayout);
This.lyjcircleviewlist=new arraylist<> (); This.mImageButton.setOnClickListener (New View.onclicklistener () {@Override public void OnClick (View v) {Lyjcir Cleview.setvisibility (View.gone)//Launch circle, upcoming loop animation View hidden final Lyjcircleview item=new Lyjcircleview (
Xiuyixiuactivity.this, Mimagebutton.getwidth (), Mimagebutton.getheight (), statusbarheight); Animator Spreadanim = Animatorinflater.lOadanimator (Xiuyixiuactivity.this, r.animator.circle_spread_animator); Spreadanim.addlistener (New Animator.animatorlistener () {@Override public void Onanimationstart (animator Animati ON) {} @Override public void Onanimationend (animator animation) {Item.setisspreadflag (true);/animation Line complete, Mark @Override public void Onanimationcancel (animator animation) {} @Override Publ
IC void Onanimationrepeat (animator animation) {}});
Spreadanim.settarget (item);
Spreadanim.start ();
Lyjcircleviewlist.add (item);
Relativelayout.addview (item);
Relativelayout.invalidate ();
Message message = Handler.obtainmessage (1); handler.sendmessagedelayed (message, 10);
Send message, timed release Lyjcircleview}});
Private Handler Handler = new Handler () {public void Handlemessage (msg) {switch (msg.what) {Case 1: for (int i=0;i<lyjcircleviewlist.size (); i++) {if (lyjcircleviewlist.geT (i). Isspreadflag ()) {Relativelayout.removeview (Lyjcircleviewlist.get (i));
Lyjcircleviewlist.remove (i);
Relativelayout.invalidate ();
} if (Lyjcircleviewlist.size () <=0) {lyjcircleview.setvisibility (view.visible);
} Message Message = Handler.obtainmessage (1);
handler.sendmessagedelayed (message, 10);
Super.handlemessage (msg);
}
};
@Override public void Onwindowfocuschanged (Boolean hasfocus) {super.onwindowfocuschanged (hasfocus);
Gets the status bar height Rect frame = new Rect ();
GetWindow (). Getdecorview (). Getwindowvisibledisplayframe (frame);
Statusbarheight = Frame.top; This.mImageButton.post (New Runnable () {@Override public void run () {Lyjcircleview = new Lyjcircleview (Xiuyixiu
Activity.this, Mimagebutton.getwidth (), Mimagebutton.getheight (), statusbarheight);
Relativelayout.addview (Lyjcircleview);
Relativelayout.postinvalidate (); Load Animation anim = Animatorinflater.loadanimator (xiuyixiuactiviTy.this, R.animator.circle_scale_animator);
Anim.addlistener (New Animator.animatorlistener () {@Override public void Onanimationstart (animator animation) { @Override public void Onanimationend (animator animation) {Anim.start ();//Looping animation} @Ov Erride public void Onanimationcancel (animator animation) {} @Override public void Onanimationrepeat (Animator Animation)
{
}
});
Anim.settarget (Lyjcircleview);
Anim.start ();
}
});
}
}
The ㈢ layout file code is as follows:
<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
android:id=" @+id/xiuyixiu_relativelayout "
android:layout_width=" Match_parent
" android:layout_height= "Match_parent" >
<imagebutton
android:id= "@+id/xiuyixiu_imagebutton"
Android:layout_width= "Wrap_content"
android:layout_height= "wrap_content"
android:layout_centerinparent = "true"
android:background= "@drawable/bwa_homepage_yuyin"/>
</RelativeLayout>
Of course the above two implementation methods, I have only set the circle border, no fill, you can set to fill after the adjustment of the gradient value.
Its properties animated file Circle_scale_animator.xml:
<?xml version= "1.0" encoding= "Utf-8"?> <set xmlns:android= "Http://schemas.android.com/apk/res/android" Android:ordering= "Together" > <objectanimator android:duration= "1000" android:propertyname= "ScaleX" android:v
Aluefrom= "1.0" android:valueto= "1.2" android:valuetype= "Floattype" > </objectAnimator> <objectanimator android:duration= "1000" android:propertyname= "ScaleY" android:valuefrom= "1.0" android:valueto= "1.2" Android:valueT
Ype= "Floattype" > </objectAnimator> <objectanimator android:startoffset= "1000" android:duration= "1000" Android:propertyname= "ScaleX" android:valuefrom= "1.2" android:valueto= "1.0" android:valuetype= "Floattype" > < /objectanimator> <objectanimator android:startoffset= "1000 android:duration=" 1000 "Android:propertyName=" SC Aley "android:valuefrom=" 1.2 "android:valueto=" 1.0 "android:valuetype=" Floattype "> </objectAnimator> </
Set>
Another circle_spread_animator.xml is:
<?xml version= "1.0" encoding= "Utf-8"?> <set xmlns:android=
"http://schemas.android.com/apk/res/" Android ">
<objectanimator
android:duration=" 1000 "
android:propertyname=" ScaleY "
android: Valuefrom= "1.0"
android:valueto= "2.0"
android:valuetype= "Floattype" >
</objectAnimator>
<objectanimator
android:duration= "1000"
android:propertyname= "ScaleX"
android:valuefrom = "1.0"
android:valueto= "2.0"
android:valuetype= "Floattype" >
</objectAnimator>
</set>
The above is the detailed content of this article, I hope to help you learn.