数字选择器NumberPicker使用教程

       数字选择器NumberPicker是Android3.0之后引入的一个控件,比较常用,比如说手机常用的闹钟,可以选择小时和分钟,如果你需要兼容3.0之前版本,GitHub上有开源的项目,具体的下载地址https://github.com/SimonVT/android-numberpicker
 

基本用法

先上布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context="com.avatarmind.numberpickerdemo.MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp">

        <NumberPicker
            android:id="@+id/hourpicker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="时" />

        <NumberPicker
            android:id="@+id/minuteicker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="分" />

    </LinearLayout>


</LinearLayout>

贴出完整的主程序代码:


public class MainActivity extends AppCompatActivity implements NumberPicker.OnValueChangeListener, NumberPicker.OnScrollListener, NumberPicker.Formatter {

    private static final String TAG = "MainActivity";

    @BindView(R.id.hourpicker)
    NumberPicker hourPicker;

    @BindView(R.id.minuteicker)
    NumberPicker minutePicker;

    @BindView(R.id.valuepicker)
    NumberPicker valuePicker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        init();
    }

    private void init() {
        hourPicker.setFormatter(this);
        hourPicker.setOnValueChangedListener(this);
        hourPicker.setOnScrollListener(this);
        hourPicker.setMaxValue(24);
        hourPicker.setMinValue(0);
        hourPicker.setValue(9);

        minutePicker.setFormatter(this);
        minutePicker.setOnValueChangedListener(this);
        minutePicker.setOnScrollListener(this);
        minutePicker.setMaxValue(60);
        minutePicker.setMinValue(1);
        minutePicker.setValue(49);

        //设置为对当前值不可编辑
        hourPicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
        minutePicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);

        //这里设置为不循环显示,默认值为true
        hourPicker.setWrapSelectorWheel(false);
        minutePicker.setWrapSelectorWheel(false);
    }

    @Override
    public String format(int value) {
        Log.i(TAG, "format: value");
        String tmpStr = String.valueOf(value);
        if (value < 10) {
            tmpStr = "0" + tmpStr;
        }
        return tmpStr;
    }

    @Override
    public void onScrollStateChange(NumberPicker view, int scrollState) {
        switch (scrollState) {
            case NumberPicker.OnScrollListener.SCROLL_STATE_FLING:
                Log.i(TAG, "onScrollStateChange: 后续滑动(飞呀飞,根本停下来)");
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_IDLE:
                Log.i(TAG, "onScrollStateChange: 不滑动");
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                Log.i(TAG, "onScrollStateChange: 滑动中");
                break;
        }

    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        Log.i(TAG, "onValueChange: 原来的值 " + oldVal + "--新值: "
                + newVal);

    }

}

基本效果如下:
这里写图片描述
 
上述代码中,大家重点关注MainActivity实现的3个接口。
1.NumberPicker.OnValueChangeListener
2. NumberPicker.OnScrollListener
1. NumberPicker.Formatter

数字选择是可以滑动,所以需要定义一个OnValueChangeListener事件,OnScrollListener滑动事件,Formatter事件:

Formatter事件:

 @Override
    public String format(int value) {
        Log.i(TAG, "format: value");
        String tmpStr = String.valueOf(value);
        if (value < 10) {
            tmpStr = "0" + tmpStr;
        }
        return tmpStr;
    }

 
OnValueChangeListener事件:

 @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        Log.i(TAG, "onValueChange: 原来的值 " + oldVal + "--新值: "
                + newVal);

    }

 
OnScrollListener滑动事件,滑动事件有三个状态:

SCROLL_STATE_FLING:手离开之后还在滑动

SCROLL_STATE_IDLE:不滑动

SCROLL_STATE_TOUCH_SCROLL:滑动中

    @Override
    public void onScrollStateChange(NumberPicker view, int scrollState) {
        switch (scrollState) {
            case NumberPicker.OnScrollListener.SCROLL_STATE_FLING:
                Log.i(TAG, "onScrollStateChange: 后续滑动(飞呀飞,根本停下来)");
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_IDLE:
                Log.i(TAG, "onScrollStateChange: 不滑动");
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                Log.i(TAG, "onScrollStateChange: 滑动中");
                break;
        }

    }

 
 初始化操作:

 private void init() {
        hourPicker.setFormatter(this);
        hourPicker.setOnValueChangedListener(this);
        hourPicker.setOnScrollListener(this);
        hourPicker.setMaxValue(24);
        hourPicker.setMinValue(0);
        hourPicker.setValue(9);

        minutePicker.setFormatter(this);
        minutePicker.setOnValueChangedListener(this);
        minutePicker.setOnScrollListener(this);
        minutePicker.setMaxValue(60);
        minutePicker.setMinValue(1);
        minutePicker.setValue(49);

        //设置为对当前值不可编辑
        hourPicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
        minutePicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);

        //这里设置为不循环显示,默认值为true
        hourPicker.setWrapSelectorWheel(false);
        minutePicker.setWrapSelectorWheel(false);
    } 

 
由于NumberPicker默认是可以对当前正在显示的数值可编辑,因此可以通过

 hourPicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);

来设置对当前数值不可编辑。

另外,NumberPicker默认是数字是可以循环滚动的,我们可以通过

hourPicker.setWrapSelectorWheel(false);

来设置其不可以循环滚动。
 

拓展

 首先,NumberPicker也是可以显示文字的,重新定义一个NumberPicker,加载一下:

  private void valueinit() {
        String[] city = {"立水桥", "霍营", "回龙观", "龙泽", "西二旗", "上地"};
        valuePicker.setDisplayedValues(city);
        valuePicker.setMinValue(0);
        valuePicker.setMaxValue(city.length - 1);
        valuePicker.setValue(4);

        //设置为对当前值不可编辑
        valuePicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
    }

效果如下:
这里写图片描述

其次,我们可以对NumberPicker分割线的颜色,间距,以及宽度(粗细)进行调整。方法如下:

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

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

    }

    /**
     * 设置picker分割线的宽度(分割线的粗细)
     */
    private void setNumberPickerDivider(NumberPicker picker) {
        Field[] fields = NumberPicker.class.getDeclaredFields();
        for (Field f : fields) {
            if (f.getName().equals("mSelectionDividerHeight")) {
                f.setAccessible(true);
                try {
                    f.set(picker, 1);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

上述3种效果如下图:

这里写图片描述

 
最后,我们也可以通过自定义NumberPicker的方式来调整数值字体的颜色以及大小,自定义NumberPicker代码如下

/**
 * 重写NumberPicker已达到修改显示字体颜色大小
 */
public class TextColorNumberPicker extends NumberPicker {

    public TextColorNumberPicker(Context context) {
        super(context);
    }

    public TextColorNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextColorNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public void addView(View child) {
        super.addView(child);
        updateView(child);
    }

    @Override
    public void addView(View child, int width, int height) {
        super.addView(child, width, height);
        updateView(child);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
        updateView(child);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        super.addView(child, params);
        updateView(child);
    }

    public void updateView(View view) {
        if (view instanceof EditText) {
            //这里修改显示字体的属性,主要修改颜色和大小
            ((EditText) view).setTextColor(Color.parseColor("#FF0000"));
            ((EditText) view).setTextSize(20);
        }
    }
}

效果如下:
这里写图片描述

      好了,上面就是数字选择器NumberPicker的基本使用方法,小伙伴们如果有问题请留言,后续我会借助NumberPicker等来编写一个比较“精致”的时间选择器,敬请关注。

猜你喜欢

转载自blog.csdn.net/zhangqunshuai/article/details/82564139
今日推荐