iOS自定义时间滚动选择控件
程序员文章站
2023-11-30 08:08:58
本文实例为大家分享了ios自定义时间滚动选择控件的具体代码,供大家参考,具体内容如下
1.先上自定义的控件:
/**
* 滚轮选择器
* author...
本文实例为大家分享了ios自定义时间滚动选择控件的具体代码,供大家参考,具体内容如下
1.先上自定义的控件:
/** * 滚轮选择器 * author lh * data 2016/8/20 17:26 */ public class wheelview extends view { public static final string tag = "wheelview"; /** * 自动回滚到中间的速度 */ public static final float speed = 2; /** * 除选中item外,上下各需要显示的备选项数目 */ public static final int show_size = 1; private context context; private list<string> itemlist; private int itemcount; /** * item高度 */ private int itemheight = 50; /** * 选中的位置,这个位置是mdatalist的中心位置,一直不变 */ private int currentitem; private paint selectpaint; private paint mpaint; // 画背景图中单独的画笔 private paint centerlinepaint; private float centery; private float centerx; private float mlastdowny; /** * 滑动的距离 */ private float mmovelen = 0; private boolean isinit = false; private selectlistener mselectlistener; private timer timer; private mytimertask mtask; handler updatehandler = new handler() { @override public void handlemessage(message msg) { if (math.abs(mmovelen) < speed) { // 如果偏移量少于最少偏移量 mmovelen = 0; if (null != timer) { timer.cancel(); timer.purge(); timer = null; } if (mtask != null) { mtask.cancel(); mtask = null; performselect(); } } else { // 这里mmovelen / math.abs(mmovelen)是为了保有mmovelen的正负号,以实现上滚或下滚 mmovelen = mmovelen - mmovelen / math.abs(mmovelen) * speed; } invalidate(); } }; public wheelview(context context) { super(context); init(context); } public wheelview(context context, attributeset attrs) { super(context, attrs); init(context); } public void setonselectlistener(selectlistener listener) { mselectlistener = listener; } public void setwheelstyle(int style) { itemlist = wheelstyle.getitemlist(context, style); if (itemlist != null) { itemcount = itemlist.size(); resetcurrentselect(); invalidate(); } else { log.i(tag, "item is null"); } } public void setwheelitemlist(list<string> itemlist) { this.itemlist = itemlist; if (itemlist != null) { itemcount = itemlist.size(); resetcurrentselect(); } else { log.i(tag, "item is null"); } } private void resetcurrentselect() { if (currentitem < 0) { currentitem = 0; } while (currentitem >= itemcount) { currentitem--; } if (currentitem >= 0 && currentitem < itemcount) { invalidate(); } else { log.i(tag, "current item is invalid"); } } public int getitemcount() { return itemcount; } /** * 选择选中的item的index * author lh * data 2016/9/4 11:09 */ public void setcurrentitem(int selected) { currentitem = selected; resetcurrentselect(); } public int getcurrentitem() { return currentitem; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); int mviewheight = getmeasuredheight(); int mviewwidth = getmeasuredwidth(); centerx = (float) (mviewwidth / 2.0); centery = (float) (mviewheight / 2.0); isinit = true; invalidate(); } private void init(context context) { this.context = context; timer = new timer(); itemlist = new arraylist<>(); mpaint = new paint(paint.anti_alias_flag); mpaint.setstyle(style.fill); mpaint.settextalign(align.center); mpaint.setcolor(getresources().getcolor(r.color.wheel_unselect_text)); int size1 = (int) (supportdisplay.getlayoutscale()*22+0.5); mpaint.settextsize(size1); selectpaint = new paint(paint.anti_alias_flag); selectpaint.setstyle(style.fill); selectpaint.settextalign(align.center); selectpaint.setcolor(getresources().getcolor(r.color.color_1a1a1a)); int size2 = (int) (supportdisplay.getlayoutscale()*24+0.5); selectpaint.settextsize(size2); centerlinepaint = new paint(paint.anti_alias_flag); centerlinepaint.setstyle(style.fill); centerlinepaint.settextalign(align.center); centerlinepaint.setcolor(getresources().getcolor(r.color.wheel_unselect_text)); // 绘制背景 setbackground(null); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); if (isinit) { drawdata(canvas); } } private void drawdata(canvas canvas) { // 先绘制选中的text再往上往下绘制其余的text if (!itemlist.isempty()) { // 绘制中间data drawcentertext(canvas); // 绘制上方data for (int i = 1; i < show_size + 1; i++) { drawothertext(canvas, i, -1); } // 绘制下方data for (int i = 1; i < show_size + 1; i++) { drawothertext(canvas, i, 1); } } } private void drawcentertext(canvas canvas) { // text居中绘制,注意baseline的计算才能达到居中,y值是text中心坐标 float y = centery + mmovelen; fontmetricsint fmi = selectpaint.getfontmetricsint(); float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); canvas.drawtext(itemlist.get(currentitem), centerx, baseline, selectpaint); } /** * 绘制文本 * author lh * data 2016/9/4 11:10 * @param canvas 画布 * @param position 距离mcurrentselected的差值 * @param type 1表示向下绘制,-1表示向上绘制 */ private void drawothertext(canvas canvas, int position, int type) { int index = currentitem + type * position; if (index >= itemcount) { index = index - itemcount; } if (index < 0) { index = index + itemcount; } string text = itemlist.get(index); int itemheight = getheight() / (show_size * 2 + 1); float d = itemheight * position + type * mmovelen; float y = centery + type * d; fontmetricsint fmi = mpaint.getfontmetricsint(); float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); canvas.drawtext(text, centerx, baseline, mpaint); } @override public void setbackground(drawable background) { background = new drawable() { @override public void draw(canvas canvas) { itemheight = getheight() / (show_size * 2 + 1); int width = getwidth(); canvas.drawline(0, itemheight, width, itemheight, centerlinepaint); canvas.drawline(0, itemheight * 2, width, itemheight * 2, centerlinepaint); centerlinepaint.setcolor(getresources().getcolor(r.color.wheel_bg)); rect toprect = new rect(0, 0, width, itemheight); canvas.drawrect(toprect, centerlinepaint); rect bottomrect = new rect(0, itemheight * 2, width, itemheight * 3); canvas.drawrect(bottomrect, centerlinepaint); } @override public void setalpha(int alpha) { } @override public void setcolorfilter(colorfilter cf) { } @override public int getopacity() { return 0; } }; super.setbackground(background); } @override public boolean ontouchevent(motionevent event) { switch (event.getactionmasked()) { case motionevent.action_down: dodown(event); break; case motionevent.action_move: domove(event); break; case motionevent.action_up: doup(); break; default: break; } return true; } private void dodown(motionevent event) { if (mtask != null) { mtask.cancel(); mtask = null; } mlastdowny = event.gety(); } private void domove(motionevent event) { mmovelen += (event.gety() - mlastdowny); if (mmovelen > itemheight / 2) { // 往下滑超过离开距离 mmovelen = mmovelen - itemheight; currentitem--; if (currentitem < 0) { currentitem = itemcount - 1; } } else if (mmovelen < -itemheight / 2) { // 往上滑超过离开距离 mmovelen = mmovelen + itemheight; currentitem++; if (currentitem >= itemcount) { currentitem = 0; } } mlastdowny = event.gety(); invalidate(); } private void doup() { // 抬起手后mcurrentselected的位置由当前位置move到中间选中位置 if (math.abs(mmovelen) < 0.0001) { mmovelen = 0; return; } if (mtask != null) { mtask.cancel(); mtask = null; } if (null == timer) { timer = new timer(); } mtask = new mytimertask(updatehandler); timer.schedule(mtask, 0, 10); } class mytimertask extends timertask { handler handler; public mytimertask(handler handler) { this.handler = handler; } @override public void run() { handler.sendmessage(handler.obtainmessage()); } } private void performselect() { if (mselectlistener != null) { mselectlistener.onselect(currentitem, itemlist.get(currentitem)); } else { log.i(tag, "null listener"); } } public interface selectlistener { void onselect(int index, string text); } }
2.然后是时间选择控件的样式工具类
/** * 时间选择样式 * author lh * data 2016/9/4 11:05 */ public class wheelstyle { public static final int minyear = 1980; public static final int maxyear = 2020; /** * wheel style hour */ public static final int style_hour = 1; /** * wheel style minute */ public static final int style_minute = 2; /** * wheel style year */ public static final int style_year = 3; /** * wheel style month */ public static final int style_month = 4; /** * wheel style day */ public static final int style_day = 5; /** * wheel style simple day */ public static final int style_simple_day = 6; /** * wheel style set warn */ public static final int style_set_warn = 7; /** * wheel style work answer */ public static final int style_work_answer = 8; private wheelstyle() { } public static list<string> getitemlist(context context, int style) { if (style == style_hour) { return createhourstring(); } else if (style == style_minute) { return createminutestring(); } else if (style == style_year) { return createyearstring(); } else if (style == style_month) { return createmonthstring(); } else if (style == style_day) { return createdaystring(); } else if (style == style_simple_day) { return createsimpledaystring(); } else if (style == style_set_warn) { return createsetwarntimestring(); } else { throw new illegalargumentexception("style is illegal"); } } private static list<string> createhourstring() { list<string> wheelstring = new arraylist<>(); for (int i = 0; i < 24; i++) { wheelstring.add(string.format("%02d" + "时", i)); } return wheelstring; } private static list<string> createminutestring() { list<string> wheelstring = new arraylist<>(); for (int i = 0; i < 60; i++) { wheelstring.add(string.format("%02d" + "分", i)); } return wheelstring; } private static list<string> createyearstring() { list<string> wheelstring = new arraylist<>(); for (int i = minyear; i <= maxyear; i++) { wheelstring.add(integer.tostring(i)); } return wheelstring; } private static list<string> createmonthstring() { list<string> wheelstring = new arraylist<>(); for (int i = 1; i <= 12; i++) { wheelstring.add(string.format("%02d" + "月", i)); } return wheelstring; } private static list<string> createdaystring() { list<string> wheelstring = new arraylist<>(); for (int i = 1; i <= 31; i++) { wheelstring.add(string.format("%02d" + "日", i)); } return wheelstring; } private static list<string> createsimpledaystring() { list<string> wheelstring = new arraylist<>(); wheelstring.add("一天后"); wheelstring.add("两天后"); wheelstring.add("三天后"); return wheelstring; } private static list<string> createsetwarntimestring() { list<string> wheelstring = new arraylist<>(); wheelstring.add("30分钟"); wheelstring.add("60分钟"); wheelstring.add("90分钟"); wheelstring.add("120分钟"); return wheelstring; } /** * 计算闰月 * * @param month * @return */ private static boolean isleapmonth(int month) { return month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12; } /** * 计算闰年 * * @param year * @return */ private static boolean isleapyear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; } }
3.使用的xml
<com.example.view.timeview.wheelview android:id="@+id/select_time_simple_wheel" android:layout_width="match_parent" android:layout_height="150dp" android:layout_marginleft="20dp" android:layout_marginright="20dp" android:layout_weight="1" />
4.在java文件中设置mwheelview.setwheelstyle(wheelstyle.style_year);就可以显示wheelstyle类中设置的类型了。这个类中的样式种类读者可以根据自己的需要自行添加。
5.获取当前选择的项也很简单mwheelview.getcurrentitem();就能获取到控件的当前选择的项。获取到所在的项以后剩下的就是逻辑操作了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。