Android Custom Implementation Loop Wheel control wheelview_android

Source: Internet
Author: User
Tags drawtext gettext gety

First, the Android cycle Roller Effect chart is presented:

Now many places have used the wheel layout wheelview, for instance when chooses the birthday, the style resembles the system to provide the Datepickerdialog, the open source control also has many, but most is draws the interface according to the current project demand, So I wrote a wheelview of my own project.
First, this control has the following requirements :
1, the ability to cycle scrolling, when up or down to the critical value, the cycle began to scroll
2, the middle of a piece has a translucent selection area, sliding at the end, which piece in the selection area, choose this fast.
3, inherit from view to draw

And then do some key points to explain:
1, the whole control inherits from view, draws in the OnDraw. The whole consists of three modules, the entire view, the entries for each block, and the entries in the Middle selection area (an extra gray area is drawn).
2, through the dynamic settings or default settings can display the number of entries, at the top and the bottom of each add a piece, meaning that a total of drawing showcount+2 entries.
3, when the top of the number of entries sliding more than half the height of the entry, dynamic entry update: The bottom of the entry to delete the first entry, delete the first entry to the bottom of the entry.
4, the outside can set the number of entries to display, font size, color, selection hint text (figure that year word), the default selection, padding filler and so on.
5, in the ontouchevent, get the slip of the fingers of the gradient value, dynamic update all current entries.
6, in the onmeasure dynamic calculation width, all the entry width, height, starting y-coordinate and so on.
7, through the current entry and the coordinates of the selected item, more than half is considered to be selected, and slide to the corresponding position.

The following is the Wheelview code, which computes the initial value and gets the value of the outside setting:

Package Cc.wxf.view.wheel;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.util.AttributeSet;
Import android.view.MotionEvent;

Import Android.view.View;
Import java.util.ArrayList;

Import java.util.List;
 /** * Created by CCWXF on 2016/3/31.
 * * public class Wheelview extends View {public static final int font_color = Color.Black;
 public static final int font_size = 30;
 public static final int PADDING = 10;
 public static final int show_count = 3;
 public static final int SELECT = 0;
 Overall width, height, item height private int width;
 private int height;
 private int itemheight;
 Number of rows to display private int showcount = Show_count;
 The current default selected location private int select = Select;
 Font color, size, filler private int fontcolor = Font_color;
 private int fontsize = Font_size;
 private int padding = padding;
 Text list private list<string> lists;
 The secondary text for the selected item, which can be an empty private String selecttip; Item and selected items private list&Lt
 wheelitem> wheelitems = new arraylist<wheelitem> ();
 Private Wheelselect wheelselect = null;
 Hand click of the y-coordinate private float mtouchy;

 Listener Private Onwheelviewitemselectlistener listener;
 Public Wheelview {Super (context);
 Public Wheelview (context, AttributeSet attrs) {Super (context, attrs);
 Public Wheelview (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); /** * Sets the color of the font, without setting the default is black * @param fontcolor * @return/public wheelview fontcolor (int fontcolor) {This.fontcol
 or = FontColor;
 return this;  /** * Sets the size of the font, without setting the default is * @param fontsize * @return/public wheelview fontsize (int fontsize) {this.fontsize =
 FontSize;
 return this; /** * Sets the text to the upper and lower sides of the filler, the default is @param padding * @return/public wheelview padding (int padding) {this.padding
 = padding;
 return this; /** * Sets the copied text for the selected item, you can not set the * @param selecttip * @return/Public Wheelview Selecttip (String Selecttip) {this.selecttip = Selecttip;
 return this; /** * Sets the text list, must and must be set before the Build method * @param lists * @return/public Wheelview lists (list<string> lists) {thi
 s.lists = lists;
 return this;  /** * Sets the number of rows to display, without setting the default is 3 * @param showcount * @return/public wheelview showcount (int showcount) {if (showcount%
 2 = 0) {throw new IllegalStateException ("The Showcount must be odd");
 } this.showcount = Showcount;
 return this; /** * Sets the index of the default selected text, does not set default to 0 * @param select * @return/Public Wheelview Select (int select) {this.select = Selec
 T
 return this; /** * Last called method to determine if the necessary function is not called * @return/Public Wheelview build () {if (lists = null) {throw new Illegalstateex
 Ception ("This method must invoke after the method [lists]");
 return to this; @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//Total width = measurespec.gets
 Ize (Widthmeasurespec)-Getpaddingleft ()-getpaddingright (); Get the height of each item PaiNT Mpaint = new Paint ();
 Mpaint.settextsize (fontsize);
 Paint.fontmetrics metrics = Mpaint.getfontmetrics ();
 ItemHeight = (int) (METRICS.BOTTOM-METRICS.TOP) + 2 * padding;
 Initialize each of the Wheelitem initwheelitems (width, itemheight); Initialize Wheelselect wheelselect = new Wheelselect (SHOWCOUNT/2 * itemheight, Width, itemheight, Selecttip, FontColor, FontS
 ize, padding);
 Get all the Heights = ItemHeight * SHOWCOUNT;
 Super.onmeasure (Widthmeasurespec, Measurespec.makemeasurespec (height, measurespec.exactly)); /** * Create display number + 2 Wheelitem * @param width * @param itemheight/private void Initwheelitems (int width, int itemhei
 ght) {wheelitems.clear ();
  for (int i = 0; i < Showcount + 2; i++) {int starty = ItemHeight * (i-1);
  int stringindex = SELECT-SHOWCOUNT/2-1 + i;
  if (StringIndex < 0) {StringIndex = Lists.size () + StringIndex;
 Wheelitems.add (New Wheelitem (starty, Width, itemheight, FontColor, FontSize, Lists.get (StringIndex))); }} @Override Public booLean Ontouchevent (motionevent event) {switch (event.getaction ()) {Case MotionEvent.ACTION_DOWN:mTouchY = event.gety
  ();
  return true;
  Case MotionEvent.ACTION_MOVE:float dy = event.gety ()-mtouchy;
  Mtouchy = Event.gety ();
  Handlemove (DY);
  Break
  Case MotionEvent.ACTION_UP:handleUp ();
 Break
 Return Super.ontouchevent (event); /** * Process Move operation * @param dy/private void handlemove (float dy) {//adjust coordinates for (Wheelitem item:wheelitems) {item.
 adjust (dy);
 } invalidate ();
 adjust adjust ();
 /** * Handle lift operation/private void Handleup () {int index =-1;
  Get the one that should be selected for (int i = 0; i < wheelitems.size (); i++) {Wheelitem item = wheelitems.get (i); If the starty is above the midpoint of the SelectItem, the item is selected as an if (Item.getstarty () > Wheelselect.getstarty () && Item.getstarty ()
  < (Wheelselect.getstarty () + ITEMHEIGHT/2)) {index = i;
  Break //If Starty is below the midpoint of SelectItem, the previous item will be selected if (Item.getstarty () >= (Wheelselect.getstarty () + ITEMHEIGHT/2) && Item.getstarty () < (Wheelselect.getstarty () + itemheight)) {index = i-1;
  Break
 }//If no other factors are found, direct return if (index = = 1) {returns;
 //Offset Displacement float dy = wheelselect.getstarty ()-Wheelitems.get (index). Getstarty ();
 Adjust coordinates for (Wheelitem item:wheelitems) {item.adjust (dy);
 } invalidate ();
 adjust adjust ();
 Set the selection int stringindex = Lists.indexof (Wheelitems.get (index). GetText ());
  if (StringIndex!=-1) {select = StringIndex;
  if (listener!= null) {listener.onitemselect (select); }}/** * Adjust item move and loop Display/private void adjust () {//if sliding down beyond the height of half item, adjust the container if (wheelitems.get (0). Getstarty () &G
  t;=-ITEMHEIGHT/2) {//Remove last item reuse Wheelitem item = Wheelitems.remove (Wheelitems.size ()-1);
  Sets the start y-coordinate item.setstarty (wheelitems.get (0). Getstarty ()-itemheight);
  Gets the text in the container indexed int = lists.indexof (wheelitems.get (0). GetText ());
  if (index = = 1) {return;
  index-= 1;
  if (Index < 0) {index = lists.size () + index; }//Set text
  Item.settext (Lists.get (index));
  Add to the start Wheelitems.add (0, item);
  Invalidate ();
 Return //If you are sliding up to the height of half item, adjust the container if (wheelitems.get (0). Getstarty () <= (-ITEMHEIGHT/2-ItemHeight)) {//Remove first item reuse whe
  Elitem item = wheelitems.remove (0);
  Sets the starting point y-coordinate item.setstarty (Wheelitems.get (Wheelitems.size ()-1). Getstarty () + itemheight);
  Gets the text in the container indexed int = Lists.indexof (Wheelitems.get (Wheelitems.size ()-1). GetText ());
  if (index = = 1) {return;
  index = 1;
  if (index >= lists.size ()) {index = 0;
  //Set Text Item.settext (Lists.get (index));
  Add to the last side Wheelitems.add (item);
  Invalidate ();
 Return
 }/** * Gets the current selection */public int getselectitem () {return select; @Override protected void OnDraw (Canvas Canvas) {//Draw each item for (Wheelitem item:wheelitems) {Item.ondraw (Canvas
 );
 //Draw Shadow if (Wheelselect!= null) {Wheelselect.ondraw (canvas); }/** * Set listener * @param listener * @return/Public Wheelview Listener (OnwheeLviewitemselectlistener listener) {This.listener = listener;
 return this;
 public interface onwheelviewitemselectlistener{void onitemselect (int index);

 }
}

Then each entry class, drawing according to the current coordinates, changing the coordinates according to the gradient value, and so on:

Package Cc.wxf.view.wheel;
Import Android.graphics.Canvas;
Import Android.graphics.Paint;

Import Android.graphics.RectF;
 /** * Created by CCWXF on 2016/3/31.
 * * public class Wheelitem {//start y coordinate, width, height private float starty;
 private int width;
 private int height;
 Four point coordinates private RECTF rect = new RECTF ();
 Font size, color private int fontcolor;
 private int fontsize;
 private String text;

 Private Paint Mpaint = new Paint (Paint.anti_alias_flag);
 Public Wheelitem (float starty, int width, int height, int fontcolor, int fontsize, String text) {this.starty = Starty;
 This.width = width;
 This.height = height;
 This.fontcolor = FontColor;
 This.fontsize = fontsize;
 This.text = text;
 Adjust (0);
 /** * Adjusts the four-point coordinate value according to the change value of y-coordinate * @param dy */public void adjust (float dy) {starty = dy;
 Rect.left = 0;
 Rect.top = Starty;
 Rect.right = width;
 Rect.bottom = starty + height;
 public float Getstarty () {return starty; /** * Directly set y-coordinate properties, adjust four-point coordinate properties * @param starty/public void Setstarty (float starty) {this.starty = Starty;
 Rect.left = 0;
 Rect.top = Starty;
 Rect.right = width;
 Rect.bottom = starty + height;
 public void SetText (String text) {this.text = text;
 Public String GetText () {return text;
 public void OnDraw (Canvas mcanvas) {//Set pen property mpaint.settextsize (FontSize);
 Mpaint.setcolor (FontColor);
 Gets the width of the font int textWidth = (int) mpaint.measuretext (text);
 The starting point of the DrawText is the lower left corner, the y-axis starting point is baseline paint.fontmetrics metrics = Mpaint.getfontmetrics ();
 int baseLine = (int) (Rect.centery () + (metrics.bottom-metrics.top)/2-metrics.bottom);
 Center Draw Mcanvas.drawtext (text, Rect.centerx ()-TEXTWIDTH/2, BaseLine, Mpaint);

 }
}

  The last option is to draw an extra gray area in the middle area:  

Package Cc.wxf.view.wheel;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;

Import Android.graphics.Rect;
 /** * Created by CCWXF on 2016/4/1.
 */public class Wheelselect {//black box background color public static final int color_background = Color.parsecolor ("#77777777");
 Black box of the y-coordinate starting point, width, height private int starty;
 private int width;
 private int height;
 Four point coordinates private Rect Rect = new Rect ();
 You need to select the text color, size, padding private String selecttext;
 private int fontcolor;
 private int fontsize;
 private int padding;

 Private Paint Mpaint = new Paint (Paint.anti_alias_flag); Public wheelselect (int starty, int width, int height, String selecttext, int fontcolor, int fontsize, int padding) {This
 . starty = Starty;
 This.width = width;
 This.height = height;
 This.selecttext = SelectText;
 This.fontcolor = FontColor;
 This.fontsize = fontsize;
 this.padding = padding;
 Rect.left = 0;
 Rect.top = Starty;
 Rect.right = width;
 Rect.bottom = starty + height; } public int Getstarty () {return starty;
 The public void Setstarty (int starty) {this.starty = Starty;
 public void OnDraw (Canvas mcanvas) {//Draw background mpaint.setstyle (Paint.Style.FILL);
 Mpaint.setcolor (Color_background);
 Mcanvas.drawrect (rect, mpaint);
  Draw Reminder Text if (SelectText!= null) {//Set pen property mpaint.settextsize (FontSize);
  Mpaint.setcolor (FontColor);
  Gets the width of the font int textWidth = (int) mpaint.measuretext (selecttext);
  The starting point of the DrawText is the lower left corner, the y-axis starting point is baseline paint.fontmetrics metrics = Mpaint.getfontmetrics ();
  int baseLine = (int) (Rect.centery () + (metrics.bottom-metrics.top)/2-metrics.bottom);
 Draw text on the right Mcanvas.drawtext (SelectText, Rect.right-padding-textwidth, BaseLine, Mpaint);

 }
 }
}

The source code is three files, very simple, the annotation is very detailed, next is to use the file:

 Final Wheelview Wheelview = (wheelview) Findviewbyid (R.id.wheelview);
 Final list<string> lists = new arraylist<> ();
 for (int i = 0; i < i++) {
  lists.add ("Test:" + i);
 }
 Wheelview.lists (lists). FontSize (km). Showcount (5). Selecttip ("Year"). Select (0). Listener (New Wheelview.onwheelviewitemselectlistener () {
  @Override public
  void onitemselect (int index) {
  log.d ("CC"). "Current Select:" + wheelview.getselectitem () + "index:" + index + ", result=" + lists.get (index));
  }
 ). Build ();

This control is simple and simple, said complex is very complex, from the most basic OnDraw implementation, can be very high flexibility to customize their needs.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

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.