关于定制日期选择器DatePicker

来源:互联网 发布:centos 6 vsftp 配置 编辑:程序博客网 时间:2024/06/08 04:43


本文转载两篇有关定制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
  1. DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);  
  2. 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
  1. private void reorderSpinners() {  
  2.        mSpinners.removeAllViews();  
  3.        // We use numeric spinners for year and day, but textual months. Ask icu4c what  
  4.        // order the user's locale uses for that combination. http://b/7207103.  
  5.        String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString());  
  6.        char[] order = ICU.getDateFormatOrder(pattern);  
  7.        final int spinnerCount = order.length;  
  8.        for (int i = 0; i < spinnerCount; i++) {  
  9.            switch (order[i]) {  
  10.                case 'd':  
  11.                    mSpinners.addView(mDaySpinner);  
  12.                    setImeOptions(mDaySpinner, spinnerCount, i);  
  13.                    break;  
  14.                case 'M':  
  15.                    mSpinners.addView(mMonthSpinner);  
  16.                    setImeOptions(mMonthSpinner, spinnerCount, i);  
  17.                    break;  
  18.                case 'y':  
  19.                    mSpinners.addView(mYearSpinner);  
  20.                    setImeOptions(mYearSpinner, spinnerCount, i);  
  21.                    break;  
  22.                default:  
  23.                    throw new IllegalArgumentException(Arrays.toString(order));  
  24.            }  
  25.        }  
  26.    }  

我就在想这个系统控件特么不能设置固定的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
  1. public class YearPicker extends DatePickerDialog{  
  2.   
  3.     public YearPicker(Context context, int theme, OnDateSetListener callBack,  
  4.             int year, int monthOfYear, int dayOfMonth) {  
  5.         super(context, theme, callBack, year, monthOfYear, dayOfMonth);  
  6.           this.setTitle(year + "年");    
  7.           try {  
  8.               int year_index=getYearPosition();  
  9.               for (int i = 0; i < 3; i++) {  
  10.               
  11.                   if(year_index!=i){  
  12.                       ((ViewGroup) ((ViewGroup) this.getDatePicker().getChildAt(0)).getChildAt(0)).getChildAt(i).setVisibility(View.GONE);    
  13.                   }  
  14.             }  
  15.         } catch (Exception e) {  
  16.         }  
  17.     }  
  18.       
  19.     @Override  
  20.     public void onDateChanged(DatePicker view, int year, int month, int day) {  
  21.         // TODO Auto-generated method stub  
  22.         super.onDateChanged(view, year, month, day);  
  23.          this.setTitle(year + "年");   
  24.     }  
  25.       
  26.     private int getYearPosition(){  
  27.         char[] order = DateFormat.getDateFormatOrder(getContext());  
  28.             final int spinnerCount = order.length;  
  29.             for (int i = 0; i < spinnerCount; i++) {  
  30.                 switch (order[i]) {  
  31.                     case 'd':  
  32.                         break;  
  33.                     case 'M':  
  34.                         break;  
  35.                     case 'y':  
  36.                         return i;  
  37.                     default:  
  38.                         throw new IllegalArgumentException(Arrays.toString(order));  
  39.                 }  
  40.             }  
  41.             return 0;  
  42.     }  
  43. }  



这是最终的结果图:

                 



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




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

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


[html] view plain copy
  1. public class YearPicker extends DatePickerDialog{  
  2.   
  3.     public YearPicker(Context context, int theme, OnDateSetListener callBack,  
  4.             int year, int monthOfYear, int dayOfMonth) {  
  5.         super(context, theme, callBack, year, monthOfYear, dayOfMonth);  
  6.           this.setTitle(year + "年");    
  7.           try {  
  8.               int year_index=getYearPosition();  
  9.               for (int i = 0; i < 3; i++) {  
  10.               
  11.                   if(year_index!=i){  
  12.                       ((ViewGroup) ((ViewGroup) this.getDatePicker().getChildAt(0)).getChildAt(0)).getChildAt(i).setVisibility(View.GONE);    
  13.                   }  
  14.             }  
  15.         } catch (Exception e) {  
  16.         }  
  17.     }  
  18.       
  19.     @Override  
  20.     public void onDateChanged(DatePicker view, int year, int month, int day) {  
  21.         // TODO Auto-generated method stub  
  22.         super.onDateChanged(view, year, month, day);  
  23.          this.setTitle(year + "年");   
  24.     }  
  25.       
  26.     private int getYearPosition(){  
  27.           
  28.         char[] order=null;  
  29.         if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){  
  30.             String pattenernew DateFormat().getBestDateTimePattern(Locale.getDefault(), "yyyyMMdd");  
  31.             order=getDateFormatOrder(pattener);  
  32.         }else{  
  33.             order=DateFormat.getDateFormatOrder(getContext());  
  34.         }  
  35.             final int spinnerCount = order.length;  
  36.               
  37.             for (int i = 0; i < spinnerCount; i++){  
  38.                 System.out.println("Test  "+order[i]);  
  39.             }  
  40.             for (int i = 0; i < spinnerCount; i++) {  
  41.                 System.out.println("");  
  42.                 switch (order[i]) {  
  43.                     case 'd':  
  44.                         System.out.println("Test1  "+i);  
  45.                         break;  
  46.                     case 'M':  
  47.                         System.out.println("Test2  "+i);  
  48.                         break;  
  49.                     case 'y':  
  50.                         System.out.println("Test3  "+i);  
  51.                         return i;  
  52.                     default:  
  53.                         throw new IllegalArgumentException(Arrays.toString(order));  
  54.                 }  
  55.             }  
  56.             return 0;  
  57.     }  
  58.       
  59.       
  60.      public static char[] getDateFormatOrder(String pattern) {  
  61.             char[] result = new char[3];  
  62.             int resultIndex = 0;  
  63.             boolean sawDay = false;  
  64.             boolean sawMonth = false;  
  65.             boolean sawYear = false;  
  66.   
  67.             for (int i = 0; i < pattern.length(); ++i) {  
  68.               char ch = pattern.charAt(i);  
  69.               if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') {  
  70.                 if (ch == 'd' && !sawDay) {  
  71.                   result[resultIndex++] = 'd';  
  72.                   sawDay = true;  
  73.                 } else if ((ch == 'L' || ch == 'M') && !sawMonth) {  
  74.                   result[resultIndex++] = 'M';  
  75.                   sawMonth = true;  
  76.                 } else if ((ch == 'y') && !sawYear) {  
  77.                   result[resultIndex++] = 'y';  
  78.                   sawYear = true;  
  79.                 }  
  80.               } else if (ch == 'G') {  
  81.                 // Ignore the era specifier, if present.  
  82.               } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {  
  83.                 throw new IllegalArgumentException("Bad pattern character '" + ch + "' in " + pattern);  
  84.               } else if (ch == '\'') {  
  85.                 if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') {  
  86.                   ++i;  
  87.                 } else {  
  88.                   i = pattern.indexOf('\'', i + 1);  
  89.                   if (i == -1) {  
  90.                     throw new IllegalArgumentException("Bad quoting in " + pattern);  
  91.                   }  
  92.                   ++i;  
  93.                 }  
  94.               } else {  
  95.                 // Ignore spaces and punctuation.  
  96.               }  
  97.             }  
  98.             return result;  
  99.           }  
  100.       
  101.