The Seekbar provided by the Android system are straight-line. But sometimes we need to use the seekbar of other shapes, then we need to customize the view to implement. Here just implements a ring-shaped, similar to the other shapes.
As follows
Java code for Custom view
Package Com.lee.circleseekbar.view;import Com.lee.circleseekbar.r;import Android.content.context;import Android.content.res.typedarray;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.rectf;import Android.graphics.drawable.drawable;import Android.util.attributeset;import android.util.log;import Android.view.motionevent;import android.view.View;/** * * Circleseekbar * * @author Lee * */public class Circleseekbar extends View {private final Boolean DEBUG = true; Private final String TAG = "Circleseekbar"; Private Context mcontext = null; Private AttributeSet mattrs = null; Private drawable mthumbdrawable = null; private int mthumbheight = 0; private int mthumbwidth = 0; Private int[] Mthumbnormal = null; Private int[] mthumbpressed = null; private int mseekbarmax = 0; Private Paint mseekbarbackgroundpaint = null; Private Paint mseekbarprogresspaint = null; Private RECTF MARCRECTF = null; Private Boolean misshowprogresstext = false; Private Paint mprogresstextpaint = null; private int mprogresstextsize = 0; private int mviewheight = 0; private int mviewwidth = 0; private int mseekbarsize = 0; private int mseekbarradius = 0; private int mseekbarcenterx = 0; private int mseekbarcentery = 0; private float mthumbleft = 0; private float mthumbtop = 0; private float mseekbardegree = 0; private int mcurrentprogress = 0; Public Circleseekbar (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); Mcontext = context; Mattrs = Attrs; Initview (); } public Circleseekbar (context context, AttributeSet Attrs) {Super (context, attrs); Mcontext = context; Mattrs = Attrs; Initview (); } public Circleseekbar (context context) {super (context); Mcontext = context; Initview (); } private void Initview () {if (DEBUG) log.d (TAG, "Initview"); TypedArray Localtypedarray = mcontext.obtainstyledattributes (Mattrs, R.styleable.circleseekbar); The properties of the thumb are set by using the Android:thumb property//The Returned drawable is a statelistdrawable type, that is, the drawable list//mthumbnormal that can achieve the selected effect And mthumbpressed is used to set the effect of different states, when you click on the thumb set mthumbpressed, otherwise set mthumbnormal mthumbdrawable = Localtypedarray.getdrawable (R.STYLEABLE.CIRCLESEEKBAR_ANDROID_THUMB); Mthumbwidth = This.mThumbDrawable.getIntrinsicWidth (); Mthumbheight = This.mThumbDrawable.getIntrinsicHeight (); Mthumbnormal = new int[]{-android. R.attr.state_focused,-android. R.attr.state_pressed,-android. R.attr.state_selected,-android. R.attr.state_checked}; mthumbpressed = new int[]{android. R.attr.state_focused, Android. R.attr.state_pressed, Android. R.attr.state_selected, Android. R.attr.state_checked}; float progresswidth = Localtypedarray.Getdimension (R.styleable.circleseekbar_progress_width, 5); int progressbackgroundcolor = Localtypedarray.getcolor (R.styleable.circleseekbar_progress_background, Color.GRAY); int progressfrontcolor = Localtypedarray.getcolor (R.styleable.circleseekbar_progress_front, Color.BLUE); Mseekbarmax = Localtypedarray.getinteger (R.styleable.circleseekbar_progress_max, 100); Mseekbarprogresspaint = new Paint (); Mseekbarbackgroundpaint = new Paint (); Mseekbarprogresspaint.setcolor (Progressfrontcolor); Mseekbarbackgroundpaint.setcolor (Progressbackgroundcolor); Mseekbarprogresspaint.setantialias (TRUE); Mseekbarbackgroundpaint.setantialias (TRUE); Mseekbarprogresspaint.setstyle (Paint.Style.STROKE); Mseekbarbackgroundpaint.setstyle (Paint.Style.STROKE); Mseekbarprogresspaint.setstrokewidth (Progresswidth); Mseekbarbackgroundpaint.setstrokewidth (Progresswidth); MARCRECTF = new RECTF (); Misshowprogresstext = Localtypedarray.getboolean (R.styleable.circleseekbar_show_progress_text, false); int progresstextstroke = (int) localtypedarray.getdimension (r.styleable.circleseekbar_progress_text_stroke_width, 5 ); int progresstextcolor = Localtypedarray.getcolor (R.styleable.circleseekbar_progress_text_color, Color.GREEN); mprogresstextsize = (int) localtypedarray.getdimension (r.styleable.circleseekbar_progress_text_size, 50); Mprogresstextpaint = new Paint (); Mprogresstextpaint.setcolor (Progresstextcolor); Mprogresstextpaint.setantialias (TRUE); Mprogresstextpaint.setstrokewidth (Progresstextstroke); Mprogresstextpaint.settextsize (mprogresstextsize); Localtypedarray.recycle (); } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (widthmeas Urespec, Heightmeasurespec); if (DEBUG) log.d (TAG, "onmeasure"); Mviewwidth = GetWidth (); Mviewheight = GetHeight (); Mseekbarsize = mviewwidth > mviewheight? Mviewheight:mviewwidth; Mseekbarcenterx = MVIEWWIDTH/2; Mseekbarcentery = MVIEWHEIGHT/2; Mseekbarradius = MSEEKBARSIZE/2-MTHUMBWIDTH/2; int left = Mseekbarcenterx-mseekbarradius; int right = Mseekbarcenterx + Mseekbarradius; int top = Mseekbarcentery-mseekbarradius; int bottom = mseekbarcentery + Mseekbarradius; Marcrectf.set (left, top, right, bottom); Starting position, three o'clock direction setthumbposition (Math.toradians (Mseekbardegree)); } @Override protected void OnDraw (canvas canvas) {canvas.drawcircle (Mseekbarcenterx, Mseekbarcentery, MS Eekbarradius, Mseekbarbackgroundpaint); Canvas.drawarc (THIS.MARCRECTF, 0.0F, Mseekbardegree, False, Mseekbarprogresspaint); Drawthumbbitmap (canvas); Drawprogresstext (canvas); Super.ondraw (canvas); } private void Drawthumbbitmap (canvas canvas) {this.mThumbDrawable.setBounds ((int) mthumbleft, (int) mthumb Top, (int) (Mthumbleft + mthumbwidth), (int) (mthumbtop + mthumbheight)); This.mThumbDrawable.draw (canvas); private void Drawprogresstext (canvas canvas) {if (true = = Misshowprogresstext) {float Textwidt h = Mprogresstextpaint.measuretext ("" + mcurrentprogress); Canvas.drawtext ("" + mcurrentprogress, MSEEKBARCENTERX-TEXTWIDTH/2, Mseekbarcentery + mprogresstext SIZE/2, Mprogresstextpaint); }} @Override public boolean ontouchevent (Motionevent event) {Float eventx = Event.getx (); float Eventy = event.gety (); Switch (event.getaction ()) {case MotionEvent.ACTION_DOWN:seekTo (Eventx, Eventy, false); break; Case Motionevent.action_move: Seekto (Eventx, Eventy, false); break; Case MotionEvent.ACTION_UP:seekTo (Eventx, Eventy, true); break; } return true; } private void Seekto (float eventx, float eventy, Boolean isUp) {if (true = = Ispointonthumb (eventx, Eventy) &am p;& false = = IsUp) {mthumbdrawable.setstate (mthumbpressed); Double radian = math.atan2 (Eventy-mseekbarcentery, Eventx-mseekbarcenterx); /* * Because the value returned by atan2 is [-PI,PI] * You need to convert the Radian value so that the interval is [0,2*PI] */if (Radian < 0 ) {Radian = Radian + 2*math.pi; } if (DEBUG) log.e (TAG, "seekto radian =" + Radian); Setthumbposition (Radian); Mseekbardegree = (float) math.round (math.todegrees (radian)); mcurrentprogress = (int) (Mseekbarmax * mseekbardegree/360); Invalidate (); }else{mThumbdrawable.setstate (Mthumbnormal); Invalidate (); }} Private Boolean ispointonthumb (float eventx, float eventy) {Boolean result = false; Double distance = math.sqrt (Math.pow (Eventx-mseekbarcenterx, 2) + Math.pow (Eventy-mseekbarcentery, 2)); if (Distance < mseekbarsize && distance > (MSEEKBARSIZE/2-mthumbwidth)) {result = Tru E } return result; private void Setthumbposition (double radian) {if (DEBUG) log.v (TAG, "setthumbposition radian =" + radian) ; Double x = Mseekbarcenterx + Mseekbarradius * Math.Cos (Radian); Double y = mseekbarcentery + Mseekbarradius * Math.sin (Radian); Mthumbleft = (float) (X-MTHUMBWIDTH/2); Mthumbtop = (float) (Y-MTHUMBHEIGHT/2); }/* Adds a set method for calling in Java code */public void setprogress (int progress) {if (DEBUG) log.v (TAG, "Setp Rogress progress = "+ progress); if (prOgress > Mseekbarmax) {progress = Mseekbarmax; } if (Progress < 0) {progress = 0; } mcurrentprogress = progress; Mseekbardegree = (Progress * 360/mseekbarmax); if (DEBUG) log.d (TAG, "setprogress mseekbardegree =" + Mseekbardegree); Setthumbposition (Math.toradians (Mseekbardegree)); Invalidate (); } public int getprogress () {return mcurrentprogress; } public void Setprogressmax (int max) {if (DEBUG) log.v (TAG, "Setprogressmax max =" + max); Mseekbarmax = max; } public int Getprogressmax () {return mseekbarmax; The public void setprogressthumb (int thumbid) {mthumbdrawable = Mcontext.getresources (). getdrawable (Thumbid); } public void Setprogresswidth (int width) {if (DEBUG) log.v (TAG, "setprogresswidth width =" + width); Mseekbarprogresspaint.setstrokewidth (width); Mseekbarbackgroundpaint.setstrokewIdth (width); public void Setprogressbackgroundcolor (int color) {mseekbarbackgroundpaint.setcolor (color); public void Setprogressfrontcolor (int color) {mseekbarprogresspaint.setcolor (color); public void Setprogresstextcolor (int color) {mprogresstextpaint.setcolor (color); } public void setprogresstextsize (int size) {if (DEBUG) log.v (TAG, "setprogresstextsize size =" + size); Mprogresstextpaint.settextsize (size); } public void Setprogresstextstrokewidth (int width) {if (DEBUG) log.v (TAG, "setprogresstextstrokewidth width = "+ width"); Mprogresstextpaint.setstrokewidth (width); The public void Setisshowprogresstext (Boolean isshow) {misshowprogresstext = Isshow; }}
The XML file is as follows
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:circle_seekbar= "http// Schemas.android.com/apk/res/com.lee.circleseekbar "xmlns:tools=" Http://schemas.android.com/tools "android:layout _width= "Match_parent" android:layout_height= "match_parent" > <com.lee.circleseekbar.view.circleseekbar Android:id= "@+id/circle_seekbar" android:layout_width= "200DP" android:layout_height= "200DP" android:l Ayout_centerinparent= "true" android:thumb= "@drawable/thumb" circle_seekbar:progress_background= "@android: Col Or/darker_gray "circle_seekbar:progress_front=" @android: Color/holo_blue_light "circle_seekbar:progress_max=" "Circle_seekbar:progress_text_color=" @android: Color/holo_green_light "circle_seekbar:progress_text_size = "30DP" circle_seekbar:progress_text_stroke_width= "4DP" circle_seekbar:progress_width= "2DP" Circle_se Ekbar:show_progress_text= "true"/></relativelayout>
The Attrs property file is as follows
<?xml version= "1.0" encoding= "Utf-8"?><resources> <declare-styleable name= "Circleseekbar" > <attr name= "Android:thumb"/> <attr name= "Progress_width" format= "Dimension"/> <attr Name= "Progress_background" format= "color"/> <attr name= "Progress_front" format= "color"/> < attr name= "Progress_max" format= "integer"/> <attr name= "Show_progress_text" format= "boolean"/> <attr name= "Progress_text_stroke_width" format= "Dimension"/> <attr name= "Progress_text_color" format= "Color"/> <attr name= "progress_text_size" format= "Dimension"/> </declare-styleable></ Resources>
Under Activity file
Package Com.lee.circleseekbar;import Android.app.activity;import Android.graphics.color;import android.os.Bundle; Import Com.lee.circleseekbar.view.circleseekbar;public class Mainactivity extends Activity { @Override protected void OnCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); Circleseekbar Circleseekbar = (circleseekbar) Findviewbyid (R.id.circle_seekbar); Circleseekbar.setprogress (+); Circleseekbar.setprogressfrontcolor (color.red); Circleseekbar.setprogresswidth ();} }
Demo
http://download.csdn.net/detail/ly0904010214/8370879
Custom View Implementation Ring Seekbar