关于定制日期选择器DatePicker

xiaoxiao2021-02-28  128

本文转载两篇有关定制datepicker的相关文章:

第一篇:DatePickerDialog的月份为英文转成数字 (转自:http://blog.csdn.net/zuohenghengl/article/details/52777021 )

在项目中,发现使用日期选择器的时候,不同手机系统日期选择框显示的日期不同,有的是中文的,有的是英文!之前以为是系统语言的问题,后面发现其实不是,是Android的日期选择框的bug。

一、现附上效果图,图片的黑白,只是主题不同而已

  

二、现在给出将月份都转换成数字的方法:

1、首先提供两个链接,帮助理解

(1)将日期选择框的年月日进行排序           http://blog.csdn.NET/lintcgirl/article/details/50476684

(2)将日期选择框的月份进行值范围设置   http://blog.csdn.net/jb521125/article/details/17042083

注:1、排序年月日,是防止在获取月份的NumberPicker不会出现数组越界异常,因为不同手机他的排序是不同的

2、使用Locale.CHINA并不能解决英文的问题

[java] view plain copy DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);  Calendar c = Calendar.getInstance(Locale.CHINA);  

2、写一个NewDatePicker类继承DatePickerDialog

/** * 重写DatePickerDialog * @author Administrator * 将不同系统月份英文修改为数字 */ public class NewDatePicker extends DatePickerDialog{ /** * 月份的取值 */ private String[] mDisplayMonths = {"1", "2", "3","4", "5", "6","7", "8", "9","10", "11", "12"}; /** * 构造方法 * @param context * @param callBack * @param year * @param monthOfYear * @param dayOfMonth */ public NewDatePicker(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { super(context, callBack, year, monthOfYear, dayOfMonth); // TODO Auto-generated constructor stub } public NewDatePicker(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { super(context, theme, callBack, year, monthOfYear, dayOfMonth); // TODO Auto-generated constructor stub } /** * 重新排序 年月日(英文会出现 月 日 年的情况,所以需要排序) */ @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); LinearLayout mSpinners = (LinearLayout) findViewById(getContext().getResources().getIdentifier("android:id/pickers", null, null)); if (mSpinners != null) { NumberPicker mYearSpinner = (NumberPicker) findViewById(getContext().getResources().getIdentifier("android:id/year", null, null)); NumberPicker mMonthSpinner = (NumberPicker) findViewById(getContext().getResources().getIdentifier("android:id/month", null, null)); NumberPicker mDaySpinner = (NumberPicker)findViewById(getContext().getResources().getIdentifier("android:id/day", null, null)); mSpinners.removeAllViews(); if (mYearSpinner != null) { mSpinners.addView(mYearSpinner); } if (mMonthSpinner != null) { mSpinners.addView(mMonthSpinner); } if (mDaySpinner != null) { mSpinners.addView(mDaySpinner); } } } /** * 有了年月日的正常顺序,下面的代码就不会出现数组越界异常 */ @Override public void onDateChanged(DatePicker view, int year, int month, int day) { // TODO Auto-generated method stub super.onDateChanged(view, year, month, day); setTitle(year+"年 "+(month+1)+"月 "+day+"日"); //关键行 ((NumberPicker)((ViewGroup)((ViewGroup)view.getChildAt(0)).getChildAt(0)).getChildAt(1)).setDisplayedValues(mDisplayMonths); } }

3、上面只是设置了滑动的动态变换,我们在使用的时候要进行初始设置

public class DatePickInput extends TextView { /** * 日期框 */ private NewDatePicker mDialog; private Context context; /** * 月份的取值 */ private String[] mDisplayMonths = {"1", "2", "3","4", "5", "6","7", "8", "9","10", "11", "12"}; public DatePickInput(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.context = context; } public DatePickInput(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } public DatePickInput(Context context) { super(context); this.context = context; } @Override protected void onFinishInflate() { if (isInEditMode()) { return; } setFocusable(false); final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA); final Calendar c = Calendar.getInstance(Locale.CHINA); setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Date date = new Date(); try { date = dateFormat.parse(getText().toString()); } catch (ParseException e) { } c.setTime(date); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); mDialog = new NewDatePicker(getContext(), AlertDialog.THEME_HOLO_LIGHT,null,year,month,day); mDialog.setTitle(year+"年 "+(month+1)+"月 "+day+"日"); mDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { DatePicker datePicker = mDialog.getDatePicker(); int year = datePicker.getYear(); int month = datePicker.getMonth(); int day = datePicker.getDayOfMonth(); c.set(year, month, day); Date date = c.getTime(); Date curDate = new Date(System.currentTimeMillis());//获取当前时间 setText(dateFormat.format(c.getTime())); } }); mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub setText(""); } }); mDialog.show(); /** * 初始设置月份 */ DatePicker dp = mDialog.getDatePicker(); if (dp != null) { ((NumberPicker)((ViewGroup)((ViewGroup)dp.getChildAt(0)).getChildAt(0)).getChildAt(1)).setDisplayedValues(mDisplayMonths); } } }); } } 4、使用,只需要在配置文件中使用自定义的TextView( DatePickInput)就可以了,一点击就会弹出日期选择框

注:这里只是简单怎么使用,使用的时候还是根据你界面来直接使用就可以了

<你的包的路径.DatePickInput android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical|center_horizontal" android:layout_marginRight="20dp" android:background="@color/white" android:gravity="right|center_vertical" android:hint="请选择日期" android:inputType="datetime" android:focusable="false" android:maxLength="50" android:singleLine="true" android:textColorHint="@color/hint" />  

第二篇:

DatePickerDialog 只显示年 (解决不同语言顺序不一样的问题) (转自: http://blog.csdn.net/u012305958/article/details/49978677)

最近的项目 由于赶进度就直接使用了系统自带的日期选择器,但是做图表选择年份的时候遇到“胡同”了,只显示年份。去网上搜了下 有解决方法可以隐藏月日的(就是只让第一个位置的NumberPicker显示),但是那种方式只能在中文韩文等语言下可以,英文的话顺序是不一样的。下面2张图是中英文语言下的显示方式:

   

 这样年的位置就不固定了,所以我要继续找解决方法。由于我用的4.4的api,于是乎自己去看了下4.4的源码 ,然后找到了这个东东:下面代理里面根据当前语言格式解析出来的char[]然后顺序显示年月日的顺序,那么我的下手点就很明确了,我要找到这个char[]里面‘y’的位置。 

[html] view plain copy private void reorderSpinners() {         mSpinners.removeAllViews();         // We use numeric spinners for year and day, but textual months. Ask icu4c what         // order the user's locale uses for that combination. http://b/7207103.         String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString());         char[] order = ICU.getDateFormatOrder(pattern);         final int spinnerCount = order.length;         for (int i = 0; i < spinnerCount; i++) {             switch (order[i]) {                 case 'd':                     mSpinners.addView(mDaySpinner);                     setImeOptions(mDaySpinner, spinnerCount, i);                     break;                 case 'M':                     mSpinners.addView(mMonthSpinner);                     setImeOptions(mMonthSpinner, spinnerCount, i);                     break;                 case 'y':                     mSpinners.addView(mYearSpinner);                     setImeOptions(mYearSpinner, spinnerCount, i);                     break;                 default:                     throw new IllegalArgumentException(Arrays.toString(order));             }         }     }  

我就在想这个系统控件特么不能设置固定的Locale,那我就投机取巧判断年份是哪一个位置不就可以了嘛,这样就动态隐藏对应的NumberPicker(DatePicker内部是用NumberPicker实现的)。然后我就去研究这个ICU.getBestDateTimePattern是什么东东,发现居然是framework层的代码,我还很二的去找到了这个类,这个方法居然关联到了另外一个东西,这时候我突然切换到5.0api去编译看这个DatePicker时发现那行代码变了居然成了DateFormat.getBestDateTimePattern();  我当时对这个方法很诧异,以前4.0api上开发时都没见过这个静态方法啊,当我用4.0api去编译时 果然报错了。。这时我已经想转iOS了 毕竟我还是一个新手,对于各个版本的兼容完全是小白啊T_T...

然而看了下旁边ios开发的今天没来,我就硬着头皮去看了下4.0api上的DatePicker..发现它里面用的DateFormat.getDateFormatOrder(getContext()); 返回的就是一个char[]  

(char[] order = ICU.getDateFormatOrder(pattern);的结果)。

这个时候很兴奋啊 我想 我对版本兼容再不懂 起码知道向下兼容吧。。然后我就获取到了“y”年对应的位置。下面贴下代码:

[html] view plain copy public class YearPicker extends DatePickerDialog{        public YearPicker(Context context, int theme, OnDateSetListener callBack,              int year, int monthOfYear, int dayOfMonth) {          super(context, theme, callBack, year, monthOfYear, dayOfMonth);            this.setTitle(year + "年");              try {                int year_index=getYearPosition();                for (int i = 0; i < 3; i++) {                                  if(year_index!=i){                        ((ViewGroup) ((ViewGroup) this.getDatePicker().getChildAt(0)).getChildAt(0)).getChildAt(i).setVisibility(View.GONE);                      }              }          } catch (Exception e) {          }      }            @Override      public void onDateChanged(DatePicker view, int year, int month, int day) {          // TODO Auto-generated method stub          super.onDateChanged(view, year, month, day);           this.setTitle(year + "年");       }            private int getYearPosition(){          char[] order = DateFormat.getDateFormatOrder(getContext());              final int spinnerCount = order.length;              for (int i = 0; i < spinnerCount; i++) {                  switch (order[i]) {                      case 'd':                          break;                      case 'M':                          break;                      case 'y':                          return i;                      default:                          throw new IllegalArgumentException(Arrays.toString(order));                  }              }              return 0;      }  }  

这是最终的结果图:

                 

好久没写博客了,原谅我的表达的思路混乱,毕竟我是新手,今天这事绕了不少弯子。我觉得使用系统控件的童鞋碰到这样的问题肯定也很心烦,我就共享出来了。 我这个烂方法肯定也有考虑不到的地方,请大牛们评论里面指正。多谢。。。。。。

/-----------------------------i'm sorry  这个在5.0三星上面好像不行耶 于是乎 我又从framework代码里面找到了那个ICU.Java 然后把里面的第二个

[html] view plain copy ICU.getDateFormatOrder(pattern);copy过来   然后调用了一个新的方法  new DateFormat().getBestDateTimePattern(Locale.getDefault(), "yyyyMMdd");由于这个方法4.4以上才有 所以我加上了版本判断 4.4以下调用上面的那个方法  4.4以上调用这个方法。。。Android不是说好的向下兼容么 真是日了狗了、、代码如下。。  

[html] view plain copy public class YearPicker extends DatePickerDialog{        public YearPicker(Context context, int theme, OnDateSetListener callBack,              int year, int monthOfYear, int dayOfMonth) {          super(context, theme, callBack, year, monthOfYear, dayOfMonth);            this.setTitle(year + "年");              try {                int year_index=getYearPosition();                for (int i = 0; i < 3; i++) {                                  if(year_index!=i){                        ((ViewGroup) ((ViewGroup) this.getDatePicker().getChildAt(0)).getChildAt(0)).getChildAt(i).setVisibility(View.GONE);                      }              }          } catch (Exception e) {          }      }            @Override      public void onDateChanged(DatePicker view, int year, int month, int day) {          // TODO Auto-generated method stub          super.onDateChanged(view, year, month, day);           this.setTitle(year + "年");       }            private int getYearPosition(){                    char[] order=null;          if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){              String pattenernew DateFormat().getBestDateTimePattern(Locale.getDefault(), "yyyyMMdd");              order=getDateFormatOrder(pattener);          }else{              order=DateFormat.getDateFormatOrder(getContext());          }              final int spinnerCount = order.length;                            for (int i = 0; i < spinnerCount; i++){                  System.out.println("Test  "+order[i]);              }              for (int i = 0; i < spinnerCount; i++) {                  System.out.println("");                  switch (order[i]) {                      case 'd':                          System.out.println("Test1  "+i);                          break;                      case 'M':                          System.out.println("Test2  "+i);                          break;                      case 'y':                          System.out.println("Test3  "+i);                          return i;                      default:                          throw new IllegalArgumentException(Arrays.toString(order));                  }              }              return 0;      }                   public static char[] getDateFormatOrder(String pattern) {              char[] result = new char[3];              int resultIndex = 0;              boolean sawDay = false;              boolean sawMonth = false;              boolean sawYear = false;                for (int i = 0; i < pattern.length(); ++i) {                char ch = pattern.charAt(i);                if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') {                  if (ch == 'd' && !sawDay) {                    result[resultIndex++] = 'd';                    sawDay = true;                  } else if ((ch == 'L' || ch == 'M') && !sawMonth) {                    result[resultIndex++] = 'M';                    sawMonth = true;                  } else if ((ch == 'y') && !sawYear) {                    result[resultIndex++] = 'y';                    sawYear = true;                  }                } else if (ch == 'G') {                  // Ignore the era specifier, if present.                } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {                  throw new IllegalArgumentException("Bad pattern character '" + ch + "' in " + pattern);                } else if (ch == '\'') {                  if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') {                    ++i;                  } else {                    i = pattern.indexOf('\'', i + 1);                    if (i == -1) {                      throw new IllegalArgumentException("Bad quoting in " + pattern);                    }                    ++i;                  }                } else {                  // Ignore spaces and punctuation.                }              }              return result;            }              } 

转载请注明原文地址: https://www.6miu.com/read-73161.html

最新回复(0)