热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

iOS自定义时间滚动选择控件

这篇文章主要为大家详细介绍了iOS自定义时间滚动选择控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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 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)  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 ();
 
 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 = 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 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 createHourString() {
 List wheelString = new ArrayList<>();
 for (int i = 0; i <24; i++) {
  wheelString.add(String.format("%02d" + "时", i));
 }
 return wheelString;
 }
 
 private static List createMinuteString() {
 List wheelString = new ArrayList<>();
 for (int i = 0; i <60; i++) {
  wheelString.add(String.format("%02d" + "分", i));
 }
 return wheelString;
 }
 
 private static List createYearString() {
 List wheelString = new ArrayList<>();
 for (int i = minYear; i <= maxYear; i++) {
  wheelString.add(Integer.toString(i));
 }
 return wheelString;
 }
 
 private static List createMonthString() {
 List wheelString = new ArrayList<>();
 for (int i = 1; i <= 12; i++) {
  wheelString.add(String.format("%02d" + "月", i));
 }
 return wheelString;
 }
 
 private static List createDayString() {
 List wheelString = new ArrayList<>();
 for (int i = 1; i <= 31; i++) {
  wheelString.add(String.format("%02d" + "日", i));
 }
 return wheelString;
 }
 
 private static List createSimpleDayString() {
 List wheelString = new ArrayList<>();
 wheelString.add("一天后");
 wheelString.add("两天后");
 wheelString.add("三天后");
 return wheelString;
 }
 
 private static List createSetWarnTimeString() {
 List 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

4.在Java文件中设置mWheelView.setWheelStyle(WheelStyle.STYLE_YEAR);就可以显示WheelStyle类中设置的类型了。这个类中的样式种类读者可以根据自己的需要自行添加。

5.获取当前选择的项也很简单mWheelView.getCurrentItem();就能获取到控件的当前选择的项。获取到所在的项以后剩下的就是逻辑操作了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
author-avatar
刘刚michaelup_340
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有