First, the effect
Click Start:
Click to stop:
Second, in the mainactivity
Import Android.graphics.Paint;
Import Android.os.Bundle;
Import Android.support.v4.view.animation.LinearOutSlowInInterpolator;
Import android.support.v7.app.AppCompatActivity;
Import Android.view.View;
Import Android.widget.Button; public class Mainactivity extends Appcompatactivity implements View.onclicklistener {//private waveview mWaveView1; priv
Ate Waveview mWaveView2;
Private Button Mstart;
Private Button mstop;
Private Circleimageview Circleimageview; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (
R.layout.activity_main);
Mstart = (Button) Findviewbyid (R.id.start);
Mstop = (Button) Findviewbyid (r.id.stop);
Circleimageview = (Circleimageview) Findviewbyid (r.id.civ_info);
Circleimageview.setimageresource (R.mipmap.icon_ku);
MWaveView2 = (Waveview) Findviewbyid (R.ID.WAVE_VIEW2);
Mwaveview2.setduration (5000);
Mwaveview2.setstyle (Paint.Style.FILL_AND_STROKE); Mwaveview2.setcolor (Getresources (). GetColor (R.color.green));
Mwaveview2.setinterpolator (New Linearoutslowininterpolator ());
Mstart.setonclicklistener (this);
Mstop.setonclicklistener (this); @Override public void OnClick (View v) {switch (V.getid ()) {Case R.id.start:mwaveview2.setcolor (getresources (). Getcolo
R (R.color.green));
Mwaveview2.start ();
Circleimageview.setimageresource (R.mipmap.icon_xiao);
Break
Case R.id.stop:mwaveview2.setcolor (Getresources (). GetColor (r.color.red));
Mwaveview2.stop ();
Circleimageview.setimageresource (R.mipmap.icon_ku);
Break }
}
}
three, in Activity_main
<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= "http://schemas.android.com/apk/res/" Android "xmlns:tools=" Http://schemas.android.com/tools "android:id=" @+id/activity_main "android:layout_width=" Match_parent "android:layout_height=" match_parent "> <button android:id=" @+id/start "Android:layout_marginTop"
= "10DP" android:layout_marginleft= "10DP" android:layout_width= "wrap_content" android:layout_height= "Wrap_content" android:text= "Start"/> <button android:id= "@+id/stop" android:layout_torightof= "@id/start" Android:layout_ margintop= "10DP" android:layout_marginleft= "10DP" android:layout_width= "wrap_content" android:layout_height= "wrap _content "android:text=" Stop "/> <cn.hnshangyu.xiuyixiu.waveview android:id=" @+id/wave_view2 "Android:layout_
Width= "350DP" android:layout_height= "350DP" android:layout_centerinparent= "true" android:layout_margintop= "10DP" Android:textsize= "24DP"/> <cn.hnshangyu.xiuyixiu.circleimageview android:id= "@+id/civ_infO "android:layout_width=" 100DP "android:layout_height=" 100DP "android:layout_centerinparent=" true "android:gravity = "Center" android:src= "@color/green" android:text= "@string/app_name" android:textcolor= "@color/colorprimary"/>
four, in Waveview:
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Paint;
Import Android.util.AttributeSet;
Import Android.view.View;
Import Android.view.animation.Interpolator;
Import Android.view.animation.LinearInterpolator;
Import java.util.ArrayList;
Import Java.util.Iterator;
Import java.util.List; /** * Water Ripple effect/public class Waveview extends View {private float minitialradius=100;//Initial ripple radius private float MMAXRADIUSRA Te = 0.85f;
If Mmaxradius is not set, Mmaxradius = Minimum length * mmaxradiusrate; private float Mmaxradius; Maximum ripple radius private long mduration = 2000; A ripple from creation to vanishing duration private int mspeed = 2000;
Ripple creation speed, each 2000ms creates a private interpolator Minterpolator = new Linearinterpolator ();
Private list<circle> mcirclelist = new arraylist<circle> ();
Private Boolean misrunning;
Private Boolean Mmaxradiusset;
Private Paint Mpaint;
Private long mlastcreatetime; Private Runnable mcreatecircle = new Runnable () {@Override public void run () {if (misrunning) {nEwcircle ();
Postdelayed (Mcreatecircle, mspeed);
}
}
}; Public Waveview {This (context, null);} public Waveview (context, AttributeSet attrs) {super (con
text, attrs);
Mpaint = new Paint (Paint.anti_alias_flag);
SetStyle (Paint.Style.FILL); } public void SetStyle (Paint.style style) {Mpaint.setstyle (style) @Override protected void onsizechanged (int w, int h, int OLDW, int oldh) {if (!mmaxradiusset) {Mmaxradius = Math.min (W, h) * MMAXRADIUSRATE/2.0F;}} public void Setmaxra Diusrate (float maxradiusrate) {this.mmaxradiusrate = maxradiusrate;} public void SetColor (int color) {Mpaint.setcolor (c
Olor); /** * Start/public void start () {if (!misrunning) {misrunning = true; Mcreatecircle.run ();}/** * Stop/public void Stop () {misrunning = false;} protected void OnDraw (Canvas Canvas) {iterator<circle> iterator = Mcirclelist.itera
Tor (); while (Iterator.hasnext ()) {Circle Circle = Iterator.next (); if (System.currenttimemillis ()-Circle.mcreatetime< Mduration) {Mpaint.setalpha (Circle.getalpha ()); Canvas.drawcircle (GetWidth ()/2, GetHeight ()/2,
Circle.getcurrentradius (), mpaint);
else {iterator.remove ();}}
if (mcirclelist.size () > 0) {postinvalidatedelayed (10);}} public void Setinitialradius (float radius) {Minitialradius = radius;} public void Setduration (long duration) {This.mdur
ation = Duration; The public void Setmaxradius (float maxradius) {This.mmaxradius = Maxradius; mmaxradiusset = true;} public void Setspeed (in T speed) {mspeed = speed;} private void Newcircle () {Long currenttime = System.currenttimemillis (); if (currenttime-m
Lastcreatetime < Mspeed) {return;}
Circle Circle = new Circle ();
Mcirclelist.add (circle);
Invalidate ();
Mlastcreatetime = currenttime; Private class Circle {Private long Mcreatetime public Circle () {this.mcreatetime = System.currenttimemillis ();} Publ IC int Getalpha () {Float percent = (system.currenttimemillis ()-mcreatetime) * 1.0f/mduration; return (int) (1.0F-minterpolator.getinterpolation (percent)) * 255); public float Getcurrentradius () {Float percent = (system.currenttimemillis ()-mcreatetime) * 1.0f/mduration;
Minitialradius + minterpolator.getinterpolation (percent) * (Mmaxradius-minitialradius); } public void Setinterpolator (Interpolator interpolator) {minterpolator = Interpolator; if (minterpolator = null) {MI
Nterpolator = new Linearinterpolator (); }
}
}
Five, in Circleimageview:
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapShader;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.ColorFilter;
Import Android.graphics.Matrix;
Import Android.graphics.Paint;
Import Android.graphics.RectF;
Import Android.graphics.Shader;
Import android.graphics.drawable.BitmapDrawable;
Import android.graphics.drawable.ColorDrawable;
Import android.graphics.drawable.Drawable;
Import Android.net.Uri;
Import android.support.annotation.ColorInt;
Import Android.support.annotation.ColorRes;
Import Android.support.annotation.DrawableRes;
Import Android.util.AttributeSet;
Import Android.widget.ImageView; public class Circleimageview extends ImageView {private static final scaletype scale_type = scaletype.center_crop; privat
E static final Bitmap.config bitmap_config = Bitmap.Config.ARGB_8888;
private static final int colordrawable_dimension = 2; private static final int default_border_width = 0;
private static final int default_border_color = Color.Black;
private static final int default_fill_color = color.transparent;
Private static Final Boolean default_border_overlay = false;
Private final RECTF mdrawablerect = new RECTF ();
Private final RECTF mborderrect = new RECTF ();
Private final Matrix Mshadermatrix = new Matrix ();
Private final Paint mbitmappaint = new Paint ();
Private final Paint mborderpaint = new Paint ();
Private final Paint mfillpaint = new Paint ();
private int mbordercolor = Default_border_color;
private int mborderwidth = Default_border_width;
private int mfillcolor = Default_fill_color;
Private Bitmap Mbitmap;
Private Bitmapshader Mbitmapshader;
private int mbitmapwidth;
private int mbitmapheight;
private float Mdrawableradius;
private float Mborderradius;
Private Colorfilter Mcolorfilter;
Private Boolean Mready;
Private Boolean msetuppending;
Private Boolean Mborderoverlay;
Private Boolean mdisablecirculartransformation; Public CIrcleimageview (context) {super (context); init ();} public Circleimageview (context, AttributeSet attrs) {
This is (context, attrs, 0);
Public Circleimageview (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
TypedArray a = Context.obtainstyledattributes (Attrs, R.styleable.circleimageview, Defstyle, 0);
Mborderwidth = A.getdimensionpixelsize (R.styleable.circleimageview_civ_border_width, DEFAULT_BORDER_WIDTH);
Mbordercolor = A.getcolor (R.styleable.circleimageview_civ_border_color, Default_border_color);
Mborderoverlay = A.getboolean (R.styleable.circleimageview_civ_border_overlay, Default_border_overlay);
Mfillcolor = A.getcolor (R.styleable.circleimageview_civ_fill_color, Default_fill_color);
A.recycle ();
Init (); private void Init () {super.setscaletype (scale_type); mready = true; if (msetuppending) {setup (); msetuppending = False
; @Override public ScaleType Getscaletype () {return scale_type.} @Override public void Setscaletype (ScAletype scaletype) {if (ScaleType!= scale_type) {throw new IllegalArgumentException (String.Format ("ScaleType%s not sup
Ported. ", ScaleType)); @Override public void Setadjustviewbounds (Boolean adjustviewbounds) {if (adjustviewbounds) {throw new Illegalargumen
Texception ("Adjustviewbounds not supported.");
} @Override protected void OnDraw (Canvas Canvas) {if (mdisablecirculartransformation) {Super.ondraw (Canvas); if (Mbitmap = = null) {return;} if (Mfillcolor!= color.transparent) {canvas.drawcircle (), Mdrawablerect.centerx
Blerect.centery (), Mdrawableradius, mfillpaint);
} canvas.drawcircle (Mdrawablerect.centerx (), Mdrawablerect.centery (), Mdrawableradius, mbitmappaint); if (Mborderwidth > 0) {canvas.drawcircle (Mborderrect.centerx (), Mborderrect.centery (), Mborderradius, MBorderPaint
); } @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH); Setu
P (); @Override public void setpadding (int left, int top, int right, int bottom) {super.setpadding (left, top, right, bottom); Setup (): @Override public void Setpaddin grelative (int start, int top, int end, int bottom) {super.setpaddingrelative (start, top, end, bottom); setup (); int Getbordercolor () {return mbordercolor.} public void setBorderColor (@ColorInt int bordercolor) {if bordercolor = m
bordercolor) {return;} Mbordercolor = BorderColor;
Mborderpaint.setcolor (Mbordercolor);
Invalidate (); }/** * @deprecated use {@link #setBorderColor (int)} instead */@Deprecated public void Setbordercolorresource (@ColorRes i NT Bordercolorres) {setBorderColor (GetContext (). Getresources (). GetColor (Bordercolorres));/** * Return the color
Drawn behind the circle-shaped drawable. * @return The color drawn behind the drawable * @deprecated Fill color support is going to being removed in the future * * Deprecated public int getfillcolor () {return mfillcolor.}/** * Set a color to be drawn behind the circle-shaped drawabl E. Note that * This has no effect if the drawable are opaque or no drawable is set. * @param fillcolor the color to be drawn behind the drawable * @deprecated Fill Color Support-going to being removed in The future/@Deprecated public void Setfillcolor (@ColorInt int fillcolor) {if (FillColor = = Mfillcolor) {return;} mFi
Llcolor = FillColor;
Mfillpaint.setcolor (FillColor);
Invalidate (); }/** * Set a color to be drawn behind the circle-shaped drawable.
Note "This" has no effect if the drawable is opaque or no drawable is set. * @param fillcolorres The color resource to is resolved to a color and * drawn behind the drawable * @deprecated Fill Co Lor support is going to being removed in the future */@Deprecated public void Setfillcolorresource (@ColorRes int Fillcolorre s) {Setfillcolor (GetContext (). Getresources (). GetColor (Fillcolorres));} public int getborderwidth () {return
Mborderwidth; public void setborderwidth (int borderwidth) {if (BorderWidth = = mborderwidth) {return;} MbordErwidth = BorderWidth;
Setup (); public Boolean Isborderoverlay () {return mborderoverlay.} public void Setborderoverlay (Boolean borderoverlay) {if (bo
Rderoverlay = = Mborderoverlay) {return;} Mborderoverlay = Borderoverlay;
Setup (); public Boolean isdisablecirculartransformation () {return mdisablecirculartransformation.} public void Setdisablecirculartransformation (Boolean disablecirculartransformation) {if (mdisablecirculartransformation = =
Disablecirculartransformation) {return;} mdisablecirculartransformation = Disablecirculartransformation;
Initializebitmap (); @Override public void Setimagebitmap (Bitmap bm) {Super.setimagebitmap (BM), Initializebitmap ();} @Override public void Setimagedrawable (drawable drawable) {super.setimagedrawable (drawable); Initializebitmap ();} @Override public void Setimageresource (@DrawableRes int resid) {super.setimageresource (resid); Initializebitmap ();} @Override public void Setimageuri (Uri uri) {Super.setimageuri (URI); initializebitmAP (); @Override public void Setcolorfilter (Colorfilter CF) {if (cf = = Mcolorfilter) {return;} mcolorfilter = CF; Applycolor
Filter ();
Invalidate (); @Override public Colorfilter Getcolorfilter () {return mcolorfilter;} private void Applycolorfilter () {if (Mbitmappain
T!= null) {mbitmappaint.setcolorfilter (mcolorfilter);}} Private Bitmap getbitmapfromdrawable (drawable drawable) {if (drawable = null) {return null;} if (drawable instanceof B itmapdrawable) {return (bitmapdrawable) drawable). Getbitmap ();} try {Bitmap Bitmap; if (drawable instanceof Colordrawa BLE) {bitmap = Bitmap.createbitmap (Colordrawable_dimension, colordrawable_dimension, bitmap_config);} else {bitmap = Bi
Tmap.createbitmap (Drawable.getintrinsicwidth (), Drawable.getintrinsicheight (), bitmap_config);
} Canvas Canvas = new Canvas (bitmap);
Drawable.setbounds (0, 0, canvas.getwidth (), Canvas.getheight ());
Drawable.draw (canvas);
return bitmap;
catch (Exception e) {e.printstacktrace (); return null;}} private void Initializebitmap () {if (mdisablecirculartransformation) {mbitmap = null;} else {mbitmap = Getbitmapfromdraw
Able (getdrawable ());
Setup ();
private void Setup () {if (!mready) {msetuppending = true; return;} if (getwidth () = 0 && getheight () = 0) {
Return } if (Mbitmap = = null) {invalidate (); return;} Mbitmapshader = new Bitmapshader (Mbitmap, Shader.TileMode.CLAMP, shader.t
Ilemode.clamp);
Mbitmappaint.setantialias (TRUE);
Mbitmappaint.setshader (Mbitmapshader);
Mborderpaint.setstyle (Paint.Style.STROKE);
Mborderpaint.setantialias (TRUE);
Mborderpaint.setcolor (Mbordercolor);
Mborderpaint.setstrokewidth (Mborderwidth);
Mfillpaint.setstyle (Paint.Style.FILL);
Mfillpaint.setantialias (TRUE);
Mfillpaint.setcolor (Mfillcolor);
Mbitmapheight = Mbitmap.getheight ();
Mbitmapwidth = Mbitmap.getwidth ();
Mborderrect.set (Calculatebounds ());
Mborderradius = Math.min (Mborderrect.height ()-mborderwidth)/2.0f, (Mborderrect.width ()-mborderwidth)/2.0f); Mdrawablerect.set (MBoRderrect); if (!mborderoverlay && mborderwidth > 0) {mdrawablerect.inset (mborderwidth-1.0f, mborderwidth-1.0f);} mDr
Awableradius = Math.min (Mdrawablerect.height ()/2.0f, Mdrawablerect.width ()/2.0f);
Applycolorfilter ();
Updateshadermatrix ();
Invalidate (); Private RECTF calculatebounds () {int availablewidth = getwidth ()-Getpaddingleft ()-getpaddingright (); int Availableh
eight = GetHeight ()-Getpaddingtop ()-Getpaddingbottom ();
int sidelength = Math.min (Availablewidth, availableheight);
float left = Getpaddingleft () + (availablewidth-sidelength)/2f;
float top = getpaddingtop () + (availableheight-sidelength)/2f;
Return to New RECTF (left, top, left + sidelength, top + sidelength); } private void Updateshadermatrix () {float scale; float dx = 0; float dy = 0; Mshadermatrix.set (null); if (Mbitmapwidth * Mdrawablerect.height () > Mdrawablerect.width () * mbitmapheight) {scale = Mdrawablerect.height ()/(float) Mbitmapheig
Ht DX = (mdrawablerect.width ()-MBitMapwidth * scale) * 0.5f; else {scale = Mdrawablerect.width ()/(float) mbitmapwidth; dy = (Mdrawablerect.height ()-mbitmapheight * scale) * 0.5
F
} mshadermatrix.setscale (scale, scale);
Mshadermatrix.posttranslate ((int) (dx + 0.5f) + mdrawablerect.left, (int) (dy + 0.5f) + mdrawablerect.top);
Mbitmapshader.setlocalmatrix (Mshadermatrix); }
}
six, in Attrs
<?xml version= "1.0" encoding= "Utf-8"?> <resources> <declare-styleable name= "Circleimageview" > < attr name= "Civ_border_width" format= "Dimension"/> <attr name= "civ_border_color" format= "Color"/> <attr Name= "Civ_border_overlay" format= "boolean"/> <attr name= "civ_fill_color" format= "Color"/> declare-styleable> <declare-styleable name= "Rangeseekbar" > <attr name= "seekbarheight" format= "Dimension" "/> <attr name=" textsize "format=" Dimension "/> <attr name=" Spacebetween "format=" Dimension "/> <attr
Name= "Leftcursorbackground" format= "reference"/> <attr name= "rightcursorbackground" format= "Reference"/> <attr name= "Marktextarray" format= "reference"/> <attr name= "textcolornormal" format= "Color"/> <attr Name= "textcolorselected" format= "color"/> <attr name= "seekbarcolornormal" format= "color"/> <attr "name=" seekbarcolorselected "format=" color "/> <attr name=" automoveduration"format=" integer "/> </declare-styleable> </resources>
The above is a small set to introduce the Android to achieve water ripple effect, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!