Android self-defined implementation Loop wheel control Wheelview

Source: Internet
Author: User
Tags drawtext gety

First present

Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqv/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity /center ">


Now a lot of places have used the wheel layout wheelview, for example, in the choice of birthdays, style similar to the system-provided datepickerdialog, open source control is also very much, but mostly based on the needs of the current project to draw the interface, So I wrote a wheelview that fits my project.

First, this control has the following requirements:

1, you can cycle rolling. When you swipe up or down to a critical value, the loop starts scrolling

2, the middle piece has a piece of translucent selection area, sliding end, which piece in this selection area, choose this fast.

3. Inherit from view to draw


Then do some key points of explanation:

1. The overall control inherits from view. Draw in OnDraw. The total consists of three modules, an entire view, an entry for each block, an entry for an intermediate selection area (an additional gray area is drawn).

2, by the dynamic setting or the default setting of the number of items can be displayed in the top and bottom of each additional piece. It means to draw showcount+2 entries altogether.

3, when the top number of entries sliding more than half the height of the entry, the dynamic entry update: The most of the entry is deleted to increase the first entry, the first entry to delete the most-added entry.

4, the outside world can set the entry display number, font size, color, select the area hint text (in the picture that year word), the default selection, padding filler and so on.

5, in the ontouchevent, get the finger sliding gradient value, dynamically update all the current entries.

6, dynamic calculation of the width in onmeasure, the width of all items, height, starting y-coordinate and so on.

7. Through the current entry and the coordinates of the selected item. More than half are considered to be selected and slide to the appropriate position.


The following is the Wheelview code. The main is to calculate the initial value, get the value outside set:

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, height of item, private int width;    private int height;    private int itemheight;    The number of rows that need to be displayed private int showcount = Show_count;    The current default selected location private int select = Select;    Font color, size, padding private int fontcolor = Font_color;    private int fontSize = Font_size;    private int padding = padding;    Text list private list<string> lists;    The auxiliary text of the selected item, which can be an empty private String selecttip; //Each item and the selected item private list<wheelitem> wheelitems = new arraylist<wheelitem> ();    Private Wheelselect wheelselect = null;    Hand-clicked y-coordinate private float mtouchy;    Listener Private Onwheelviewitemselectlistener listener;    Public Wheelview (Context context) {super (context);    } public Wheelview (context context, AttributeSet Attrs) {Super (context, attrs);     } public Wheelview (context context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); }/** * Set the color of the font, do not set the default feel black * @param fontcolor * @return * * * public wheelview fontcolor (int Fontco        LOR) {this.fontcolor = FontColor;    return this;        }/** * Set the size of the font, do not set the words of the default @param fontSize * * @return * */public Wheelview fontSize (int fontSize) {        This.fontsize = fontSize;    return this; }/** * Set the text to the top and bottom of the filler. If it doesn't fit, it feels like * @param padding * @return * */public Wheelview padding (int padding) {        this.padding = padding;    return this; /** * Sets the copied text of the selected item without setting 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&LT;STRING&G T        Lists) {this.lists = lists;    return this;        }/** * Set the number of lines displayed, default 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 default selected text, does not set defaults to 0 * @param SELECT * @return */public Wheelview Select (int select) {        This.select = select;    return this; }/** * The last method called.    Infer if a function is not called * @return */public Wheelview build () {if (lists = = null) {        throw new IllegalStateException ("This method must invoke after the method [lists]");    } return this; } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//Get overall width wide = M        Easurespec.getsize (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 Wheelitem initwheelitems (width, itemheight);  Initialize Wheelselect wheelselect = new Wheelselect (SHOWCOUNT/2 * itemheight, Width, itemheight, Selecttip, FontColor,        FontSize, padding);        Get all Height heights = itemheight * SHOWCOUNT;    Super.onmeasure (Widthmeasurespec, Measurespec.makemeasurespec (height, measurespec.exactly)); }/** * Create a display number + 2 Wheelitem * @param width * @param itemheiGht */private void Initwheelitems (int width, int itemheight) {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 ()) {CA                Se 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); }/** * Handle move operation * @param dy */private void Handlemove (float dy) {//adjust coordinates for (Wheelitem ite        M:wheelitems) {item.adjust (dy);        } invalidate ();    adjusting 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); Assuming that Starty is above the midpoint of SelectItem, the item is selected as the selection if (Item.getstarty () > Wheelselect.getstarty () && item.getst                Arty () < (Wheelselect.getstarty () + ITEMHEIGHT/2)) {index = i;            Break }//Assuming Starty is below the midpoint of SelectItem, the previous item is selected as the selection if (Item.getstarty () >= (Wheelselect.getstarty () + Itemhei                GHT/2) && Item.getstarty () < (Wheelselect.getstarty () + itemheight) {index = i-1;            Break }}//Suppose not found or other factors. Direct return       if (index = =-1) {return;        }//Get offset of the displacement float dy = wheelselect.getstarty ()-Wheelitems.get (index). Getstarty ();        Adjust coordinates for (Wheelitem item:wheelitems) {item.adjust (dy);        } invalidate ();        adjusting adjust ();        Set the selection int stringindex = Lists.indexof (Wheelitems.get (index). GetText ());            if (stringindex! =-1) {select = StringIndex;            if (listener! = null) {listener.onitemselect (select); }}}/** * Adjust the item move and loop display */private void adjust () {//Assuming that the slide down exceeds the height of half item, adjust the container if (whe Elitems.get (0). Getstarty () >=-ITEMHEIGHT/2) {//Remove last item reuse Wheelitem item = Wheelitems.remov            E (Wheelitems.size ()-1);            Sets the starting point Y coordinate item.setstarty (wheelitems.get (0). Getstarty ()-itemheight);            Get the text in the container index int index = lists.indexof (wheelitems.get (0). GetText ()); Ifindex = =-1) {return;            } index-= 1;            if (Index < 0) {index = lists.size () + index;            }//Set Text Item.settext (Lists.get (index));            Added to the beginning Wheelitems.add (0, item);            Invalidate ();        Return            }//Assuming that the upward slide exceeds the height of the half item, adjust the container if (wheelitems.get (0). Getstarty () <= (-ITEMHEIGHT/2-itemheight)) {            Remove the first item reuse Wheelitem item = wheelitems.remove (0);            Sets the starting point Y coordinate Item.setstarty (Wheelitems.get (Wheelitems.size ()-1). Getstarty () + itemheight);            Get the text in the container index int index = 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 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 the item for (Wheelitem Item:wheelitems) {        Item.ondraw (canvas);        }//Draw Shadow if (wheelselect! = null) {Wheelselect.ondraw (canvas); }}/** * Set listener * @param listener * @return * */Public Wheelview Listener (onwheelviewitemselectlis        Tener listener) {This.listener = listener;    return this;    } public interface onwheelviewitemselectlistener{void onitemselect (int index); }}


Then each entry class is drawn according to the current coordinates, changing the coordinates according to the gradient values:

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 = STA        Rty;        This.width = width;        This.height = height;        This.fontcolor = FontColor;        This.fontsize = fontSize;        This.text = text;    Adjust (0); }/** * Based on the change value of the y-coordinate.        Adjust the four-point coordinate value * @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;  }/** * Set the y-coordinate property directly, adjust the four-point coordinate property * @param starty */public void Setstarty (float starty) {this.starty =        Starty;        Rect.left = 0;        Rect.top = Starty;        Rect.right = width;    Rect.bottom = starty + height;    The 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 drawing 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); }}


Finally, select items. 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");    The y-coordinate of the black box starts, width, height, private int starty;    private int width;    private int height;    Four point coordinate private rect rect = new rect ();    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;    } 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 drawing 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); }    }}


Source code on three files, very easy. The gaze is very specific, and the next step 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 (+). 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 easy to say. Complexity is also complex, from the most basic OnDraw, can be highly flexible to customize their own needs.

Demoproject is not provided, the use is very easy.

Android self-defined implementation Loop wheel control Wheelview

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.