修改DatePicker、  NumberPicker 默认属性(间距、分割线颜色和高度)

1、基本使用

1、简单使用

   <DatePicker
        android:startYear="2017"
        android:endYear="2018"
        android:calendarViewShown="false"
        android:spinnersShown="true"
        android:datePickerMode="spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
  • calendarViewShown:是否显示ClendarView日历组件
  • spinnersShown:是否显示Spinner日期选择组件
  • datePickerMode:有两个值
  • calendar:日历形式的日期选择器
  • Spinner:滚动的
calendarViewShown="false",spinnersShown="true",使用日期组件
calendarViewShown="true",spinnersShown="true",使用日历和日期组件
使用日历组件

2、初始化datePicker

   private void initPicker() {
        //设置中文日历
        calendar = Calendar.getInstance(Locale.CHINA);
        int year=calendar.get(Calendar.YEAR);
        int month=calendar.get(Calendar.MONTH);
        int day=calendar.get(Calendar.DAY_OF_MONTH);
        int week=calendar.get(Calendar.DAY_OF_WEEK);

        //初始化datePicker
        datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    
            }
        });

        //设置最大日期
        GregorianCalendar g=new GregorianCalendar(year,month,day+7);
        datePicker.setMaxDate(g.getTimeInMillis());

    } 

3、初始化numberPicker

    private void initPicker() {
        ...
        //设置numberPicker展示的值,一个数组
        numberPicker.setDisplayedValues(times);
        //numberPicker的最小值
        numberPicker.setMinValue(0);
        //numberPicker的最大值
        numberPicker.setMaxValue(length-1);
        //numberPicker当前值
        numberPicker.setValue(preId);
    
        numberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

    }

3、设置NumberPicker,中间的EditView不可以点击

中间不可点击修改
        datePicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);

4、设置NumberPicker,不能循环

        numPicker.setWrapSelectorWheel(false);

numberpicker的循环滚动需要遍历所有元素,可能会导致的数组越界(当再次为numberpicker赋值时...)

2、获得DatePicker的三个NumberPicker

DatePicker中选择年月日的部分是三个NumberPicker,名字分别为mYearSpinner,mMonthSpinner、mDaySpinner,它们三个平铺在一个LinearLayout中,可以通过如下方法得到这些NumberPicker:

  • 利用java反射技术得到DatePicker内部的属性(三个NumberPicker),并对其进行操作(适用于API<21)
  • 可以通过三个NumberPicker的资源id,得到这些view(API>=21,这三个NumberPicker,不是DatePicker内部的属性)。或者根据view树的结构,得到NumberPicker
DatePicker
public class DatePicker extends FrameLayout {
    ...
    /**
     * A delegate implementing the basic DatePicker
     */
    private static class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
        ...
        private final LinearLayout mSpinners;
        private final NumberPicker mDaySpinner;
        private final NumberPicker mMonthSpinner;
        private final NumberPicker mYearSpinner;
    }
}

代码如下:


private void getNumberPicker() {
    Class<? extends DatePicker> c =DatePicker.class;
    Field fd = null, fm = null, fy = null;
    View daySpinner = null;
    View monthSpinner= null;
    View yearSpinner = null;
    // 系统版本大于5.0
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        //获取资源的id
        int daySpinnerId = Resources.getSystem().getIdentifier("day", "id", "android");
        int monthSpinnerId = Resources.getSystem().getIdentifier("month", "id", "android");
        int yearSpinnerId = Resources.getSystem().getIdentifier("year", "id", "android");
        if (daySpinnerId != 0 && monthSpinnerId!=0 && yearSpinnerId!=0) {
            daySpinner = this.findViewById(daySpinnerId);
            monthSpinner = this.findViewById(monthSpinnerId);
            yearSpinner = this.findViewById(yearSpinnerId);
        }
            //或者
           /*LinearLayout llFirst = (LinearLayout) getChildAt(0);
            LinearLayout mSpinners = (LinearLayout) llFirst.getChildAt(0);
            for (int i = 0; i < mSpinners.getChildCount(); i++)
            {
                NumberPicker picker = (NumberPicker) mSpinners.getChildAt(i);
                mPickers.add(i, picker);
            }
            return;*/
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        // 系统版本大于4.0
        fd = c.getDeclaredField("mDaySpinner");
        fm = c.getDeclaredField("mMonthSpinner");
        fy = c.getDeclaredField("mYearSpinner");
        if(fd!=null && fm!=null &&fy!=null){
            // 对字段获取设置权限
            fd.setAccessible(true);
            fm.setAccessible(true);
            fy.setAccessible(true);
            // 得到对应的控件
            daySpinner = (View) fd.get(this);
            monthSpinner= (View) fm.get(this);
            yearSpinner= (View) fy.get(this);
        }
    } else {
        fd = c.getDeclaredField("mDayPicker");
        fm = c.getDeclaredField("mMonthPicker");
        fy = c.getDeclaredField("mYearPicker");
        if(fd!=null && fm!=null &&fy!=null){
            // 对字段获取设置权限
            fd.setAccessible(true);
            fm.setAccessible(true);
            fy.setAccessible(true);
            // 得到对应的控件
            daySpinner = (View) fd.get(this);
            monthSpinner= (View) fm.get(this);
            yearSpinner= (View) fy.get(this);
        }
    }
    if (daySpinner != null && monthSpinner != null && yearSpinner != null) {
        daySpinner.setVisibility(View.GONE);
        if(daySpinner instanceof NumberPicker && monthSpinner instanceof NumberPicker && yearSpinner instanceof NumberPicker ){
            mPickers.add((NumberPicker) daySpinner);
            mPickers.add((NumberPicker) monthSpinner);
            mPickers.add((NumberPicker) yearSpinner);
        }
    }

}

注意:getIdentifier(String name, String defType, String defPackage) :获取资源ID
资源的名称 /资源的类型(drawable,string等) /包名

3、修改NumberPicker
 
    /**
     * 设置picker之间的间距
     */
    private void setPickerMargin(NumberPicker picker) {
        LinearLayout.LayoutParams p= (LinearLayout.LayoutParams) picker.getLayoutParams();
        p.setMargins(0,0,0,0);
        if(Build.VERSION.SDK_INT> Build.VERSION_CODES.JELLY_BEAN_MR1){
            p.setMarginStart(0);
            p.setMarginEnd(0);
        }
    }

    /**
     * 设置picker分割线的颜色
     */
    private void setDividerColor(NumberPicker picker) {
        Field field=NumberPicker.class.getDeclaredField("mSelectionDivider");
        if(field!=null){
            field.setAccessible(true);
            field.set(picker,new ColorDrawable(Color.RED));
        }
    }

    /**
     * 设置picker分割线的宽度
     */
    private void setNumberPickerDivider(NumberPicker picker) {
        Field[] fields=NumberPicker.class.getDeclaredFields();
        for(Field f:fields){
            if(f.getName().equals("mSelectionDividerHeight")){
                f.setAccessible(true);
                f.set(picker,1);
            break;
            }
        }
    }
修改前
修改后

参考:Android NumberPicker 修改分割线颜色和高度及字体颜色大小更改DatePicker中年月日的间隔和分隔线颜色

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,535评论 0 17
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,245评论 4 61
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,372评论 25 708
  • 南风萧萧吹散广陵曲十年安然洛阳路胡尘又起惹离乱如故牧歌飘 交错九州江湖 战马趋 再咏絮石头城下波涛怒谁又堪 兵戈苦...
    梦饮千樽月阅读 489评论 0 48
  • 麻烦问一下 大家 这个系统服务中的 时间与地点 流量是怎么产生的呢?我App中只是使用了CLLocationMan...
    wrlynxayy阅读 198评论 0 0