当前位置:   article > 正文

Android自定义时间选择器_android 时间选择器

android 时间选择器

效果图

一、添加NumberPicker开源库 

需要添加以下控件 

仓库地址: https://github.com/ShawnLin013/NumberPicker

implementation 'io.github.ShawnLin013:number-picker:2.4.13'

二、 添加弹出框主题样式

在drawable文件夹下新建一个bg_bottom_dialog.xml,添加以下代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android">
  3. <!-- 圆角 -->
  4. <corners
  5. android:topLeftRadius="20dp"
  6. android:topRightRadius="20dp" />
  7. <!-- 填充色 -->
  8. <solid android:color="@color/white" />
  9. <!--内边距-->
  10. <padding
  11. android:top="12dp"
  12. android:left="16dp"
  13. android:right="16dp"
  14. android:bottom="16dp" />
  15. </shape>

三、添加时间选择器布局 

在layout文件夹下新建view_time_picker.xml文件,添加以下代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. xmlns:app="http://schemas.android.com/apk/res-auto"
  7. android:background="@drawable/bg_bottom_dialog">
  8. <TextView
  9. android:id="@+id/cancel"
  10. android:layout_width="wrap_content"
  11. android:layout_height="40dp"
  12. app:layout_constraintTop_toTopOf="parent"
  13. app:layout_constraintLeft_toLeftOf="parent"
  14. app:layout_constraintBottom_toTopOf="@id/year"
  15. android:gravity="center"
  16. android:text="取消"
  17. android:textColor="#666666"
  18. android:clickable="true"
  19. android:focusable="true" />
  20. <TextView
  21. android:id="@+id/title"
  22. android:layout_width="0dp"
  23. android:layout_height="40dp"
  24. app:layout_constraintTop_toTopOf="parent"
  25. app:layout_constraintLeft_toRightOf="@id/cancel"
  26. app:layout_constraintBottom_toTopOf="@id/year"
  27. app:layout_constraintRight_toLeftOf="@id/ok"
  28. android:gravity="center"
  29. android:text="出生日期"
  30. android:textColor="#333333"
  31. android:textStyle="bold" />
  32. <TextView
  33. android:id="@+id/ok"
  34. android:layout_width="wrap_content"
  35. android:layout_height="40dp"
  36. app:layout_constraintRight_toRightOf="parent"
  37. app:layout_constraintTop_toTopOf="parent"
  38. app:layout_constraintBottom_toTopOf="@id/year"
  39. android:gravity="center"
  40. android:text="确定"
  41. android:textColor="#1580C8"
  42. android:textStyle="bold"
  43. android:clickable="true"
  44. android:focusable="true" />
  45. <com.shawnlin.numberpicker.NumberPicker
  46. android:id="@+id/year"
  47. android:layout_width="0dp"
  48. android:layout_height="0dp"
  49. app:layout_constraintTop_toBottomOf="@id/title"
  50. app:layout_constraintBottom_toBottomOf="parent"
  51. app:layout_constraintLeft_toLeftOf="parent"
  52. app:layout_constraintRight_toLeftOf="@id/month"
  53. app:np_formatter="%d"
  54. app:np_dividerColor="#2B000000"
  55. app:np_dividerThickness="1px"
  56. app:np_selectedTextColor="#333333"
  57. app:np_selectedTextSize="18sp"
  58. app:np_textSize="14sp"
  59. app:np_wheelItemCount="5"
  60. app:np_wrapSelectorWheel="false" />
  61. <com.shawnlin.numberpicker.NumberPicker
  62. android:id="@+id/month"
  63. android:layout_width="0dp"
  64. android:layout_height="0dp"
  65. app:layout_constraintTop_toBottomOf="@id/title"
  66. app:layout_constraintBottom_toBottomOf="parent"
  67. app:layout_constraintLeft_toRightOf="@id/year"
  68. app:layout_constraintRight_toLeftOf="@id/day"
  69. app:np_dividerColor="#2B000000"
  70. app:np_dividerThickness="1px"
  71. app:np_selectedTextColor="#333333"
  72. app:np_selectedTextSize="18sp"
  73. app:np_textSize="14sp"
  74. app:np_wheelItemCount="5"
  75. app:np_wrapSelectorWheel="false" />
  76. <com.shawnlin.numberpicker.NumberPicker
  77. android:id="@+id/day"
  78. android:layout_width="0dp"
  79. android:layout_height="0dp"
  80. app:layout_constraintTop_toBottomOf="@id/title"
  81. app:layout_constraintBottom_toBottomOf="parent"
  82. app:layout_constraintLeft_toRightOf="@id/month"
  83. app:layout_constraintRight_toRightOf="parent"
  84. app:np_dividerColor="#2B000000"
  85. app:np_dividerThickness="1px"
  86. app:np_selectedTextColor="#333333"
  87. app:np_selectedTextSize="18sp"
  88. app:np_textSize="14sp"
  89. app:np_wheelItemCount="5"
  90. app:np_wrapSelectorWheel="false" />
  91. </androidx.constraintlayout.widget.ConstraintLayout>

四、添加时间选择器类 

 添加以下类,复制即用

  1. import java.util.ArrayList;
  2. import java.util.Calendar;
  3. import java.util.List;
  4. import com.google.android.material.bottomsheet.BottomSheetDialog;
  5. import com.onegrid.app.npmn.R;
  6. import com.shawnlin.numberpicker.NumberPicker;
  7. import android.content.Context;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10. import android.widget.FrameLayout;
  11. import android.widget.TextView;
  12. /**
  13. * 时间选择器
  14. *
  15. * @author DengLS
  16. * @date 2023/01/12
  17. */
  18. public class TimePickerCustom {
  19. private final BottomSheetDialog bottomDialog;
  20. private final NumberPicker year;
  21. private final NumberPicker month;
  22. private final NumberPicker day;
  23. /**
  24. * 时间选择回调
  25. *
  26. * @author DengLS
  27. * @date 2023/01/12
  28. */
  29. public interface TimePickerCallback {
  30. /**
  31. * 回调
  32. *
  33. * @param year 年
  34. * @param month 月
  35. * @param day 日
  36. */
  37. void setDate(int year, int month, int day);
  38. }
  39. public TimePickerCustom(Context context, String title, TimePickerCallback callback) {
  40. // 设置时间选择器的布局以及弹窗的高度
  41. bottomDialog = getBottomDialog(context, R.layout.view_time_picker, dpToPx(context, 350));
  42. Calendar calendar = Calendar.getInstance();
  43. // 设置标题
  44. ((TextView)bottomDialog.findViewById(R.id.title)).setText(title);
  45. // 年
  46. year = (NumberPicker)bottomDialog.findViewById(R.id.year);
  47. int yearNow = calendar.get(Calendar.YEAR);
  48. year.setMinValue(yearNow - 100);
  49. year.setMaxValue(yearNow + 100);
  50. year.setValue(yearNow);
  51. // 月
  52. month = (NumberPicker)bottomDialog.findViewById(R.id.month);
  53. String[] monthNum = new String[12];
  54. for (int i = 0; i < 12; i++) {
  55. monthNum[i] = (i + 1) + "月";
  56. }
  57. month.setMinValue(1);
  58. month.setMaxValue(monthNum.length);
  59. month.setDisplayedValues(monthNum);
  60. month.setValue(calendar.get(Calendar.MONTH));
  61. // 日
  62. day = (NumberPicker)bottomDialog.findViewById(R.id.day);
  63. day.setMinValue(1);
  64. int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  65. String[] newDays = getNewDays(days);
  66. day.setMaxValue(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
  67. day.setDisplayedValues(newDays);
  68. day.setValue(calendar.get(Calendar.DATE));
  69. // 年份和月份更改时对应的天数需要更改
  70. year.setOnValueChangedListener((picker, oldVal, newVal) -> {
  71. updateNumberOfDays();
  72. day.setValue(calendar.get(Calendar.DATE));
  73. });
  74. month.setOnValueChangedListener((picker, oldVal, newVal) -> {
  75. updateNumberOfDays();
  76. day.setValue(calendar.get(Calendar.DATE));
  77. });
  78. // 取消按钮和确定按钮事件绑定
  79. View cancel = bottomDialog.findViewById(R.id.cancel);
  80. View ok = bottomDialog.findViewById(R.id.ok);
  81. if (cancel != null) {
  82. cancel.setOnClickListener(v -> bottomDialog.dismiss());
  83. }
  84. if (ok != null) {
  85. ok.setOnClickListener(v -> {
  86. bottomDialog.dismiss();
  87. callback.setDate(year.getValue(), month.getValue(), day.getValue());
  88. });
  89. }
  90. }
  91. /**
  92. * 底部弹出框
  93. *
  94. * @param id 弹窗中的布局
  95. * @param height 弹窗高度
  96. */
  97. private BottomSheetDialog getBottomDialog(Context context, Integer id, int height) {
  98. BottomSheetDialog bottomSheet = new BottomSheetDialog(context);
  99. // 设置对框框中的布局
  100. bottomSheet.setContentView(id);
  101. // 设置点击外部是否可以取消
  102. bottomSheet.setCancelable(true);
  103. FrameLayout bottom = (FrameLayout)bottomSheet.findViewById(com.google.android.material.R.id.design_bottom_sheet);
  104. if (bottom != null) {
  105. // 设置背景透明颜色
  106. bottom.setBackgroundResource(R.color.transparent);
  107. // 修改弹窗的高度
  108. ViewGroup.LayoutParams layoutParams = bottom.getLayoutParams();
  109. layoutParams.height = height;
  110. bottom.setLayoutParams(layoutParams);
  111. }
  112. return bottomSheet;
  113. }
  114. /**
  115. * dp转px
  116. */
  117. private int dpToPx(Context context, float dp) {
  118. return (int)(dp * context.getResources().getDisplayMetrics().density + 0.5);
  119. }
  120. /**
  121. * 显示
  122. */
  123. public void show() {
  124. bottomDialog.show();
  125. }
  126. /**
  127. * 设置选中年份
  128. *
  129. * @param yearValue 年
  130. */
  131. public void setYearValue(int yearValue) {
  132. year.setValue(yearValue);
  133. updateNumberOfDays();
  134. }
  135. /**
  136. * 设置选中月份
  137. *
  138. * @param monthValue 月
  139. */
  140. public void setMonthValue(int monthValue) {
  141. month.setValue(monthValue);
  142. updateNumberOfDays();
  143. }
  144. /**
  145. * 设置选中天数
  146. *
  147. * @param dayValue 天
  148. */
  149. public void setDayValue(int dayValue) {
  150. day.setValue(dayValue);
  151. }
  152. /**
  153. * 更新天数
  154. *
  155. */
  156. private void updateNumberOfDays() {
  157. Calendar calendar = Calendar.getInstance();
  158. calendar.set(Calendar.YEAR, year.getValue());
  159. calendar.set(Calendar.MONTH, (month.getValue() - 1));
  160. calendar.set(Calendar.DATE, 1);
  161. calendar.roll(Calendar.DATE, -1);
  162. int date = calendar.get(Calendar.DATE);
  163. day.setMaxValue(date);
  164. day.setDisplayedValues(getNewDays(date));
  165. }
  166. /**
  167. * 格式化天数
  168. *
  169. * @param days 天数
  170. * @return {@link String[]}
  171. */
  172. private String[] getNewDays(int days) {
  173. List<String> dayList = new ArrayList<>();
  174. for (int i = 0; i < days; i++) {
  175. dayList.add((i + 1) + "日");
  176. }
  177. return dayList.toArray(new String[dayList.size()]);
  178. }
  179. }

 五、使用

  1. TimePickerCustom timePickerCustom = new TimePickerCustom(context, "标题", (year, month, day) -> {
  2. // 确定按钮的回调
  3. Log.i("timePickerCustom", year + "------" + month + "--------" + day);
  4. });
  5. // 弹出
  6. timePickerCustom.show();

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/278870
推荐阅读
相关标签