数字选择器NumberPicker是Android3.0之后出的一个控件,所以如果要兼容3.0之前的版本就需要用到GitHub上的开源项目,下载地址是https://github.com/SimonVT/android-numberpicker
设置最大值
mNumberPicker.setMaxValue(10); //设置最大值
设置最小值
mNumberPicker.setMinValue(0); //设置最小值
设置当前值
mNumberPicker.setValue(5); //设置当前值
获取当前值
int value = mNumberPicker.getValue(); //获取当前值
有一点需要注意的数值不能用负数
我们只需要使用一个方法就可以了
public void setDisplayedValues(String[] displayedValues)
所以代码可以这么写,注意最大值是数组的最大下标
String[] datas = new String[]{"北京","上海","广州","深圳"};
mNumberPicker.setDisplayedValues(datas); //设置文字
mNumberPicker.setMaxValue(datas.length - 1); //设置最大值,最大值是datas[3]
NumberPicker有三个监听分别是OnValueChangeListener、OnScrollListener、Formatter
代码如下
mNumberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
/**
* 每当选择的值改变时都会调用一次
* @param oldVal 改变前的值
* @param newVal 改变后的值
*/
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
//做想做的事
}
});
每当选择的值改变都会调用一次这个方法,选择的值改变也就是显示在中间的那个值改变
实例代码如下
mNumberPicker.setOnScrollListener(new NumberPicker.OnScrollListener() {
@Override
public void onScrollStateChange(NumberPicker view, int scrollState) {
switch (scrollState){
case SCROLL_STATE_FLING:
//手离开之后还在滑动
break;
case SCROLL_STATE_IDLE:
//停止滑动
break;
case SCROLL_STATE_TOUCH_SCROLL:
//正在滑动
break;
}
}
});
滑动事件就是监听控件滑动时的状态
滑动事件有三个状态
实例代码如下
mNumberPicker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(int value) {
//做一些格式转换
return "返回转换后要显示的内容";
}
});
这个监听是用于做一些格式转换的,比如把10以下的数前面加个0显示(01、02、03…..),也能理解为转换器,下面我会为大家介绍如何利用Formatter监听设置10以下的数前面加0显示。
我们需要注意一下不能返回空
实现这个效果我们只需要设置Formatter监听,让小于10的数前面加个0再输出
mNumberPicker.setMaxValue(20);
mNumberPicker.setMinValue(0);
mNumberPicker.setValue(0);
mNumberPicker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(int value) {
String data;
if (value < 10) {
data = "0" + value;//让小于10的数前面加个0再输出
} else {
data = String.valueOf(value); //大于10的数就不变
}
return data;
}
});
要设置是否循环滚动只需要使用一个方法就可以了
mNumberPicker.setWrapSelectorWheel(true); //设置循环滚动
设置false代表不循环滚动,true代表循环滚动
该方法需要注意的是
当我们用手指点一下显示的数值会发现竟然可以输入,有些时候我们需要禁止输入,该怎么办呢?我介绍两种常用的方法一种是用在代码里设置,一种是在xml里面设置。
只需要使用一个方法就可以了
mNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); //禁止输入
设置NumberPicker的属性
android:focusable="true"
android:focusableInTouchMode="true"
这样就可以禁止输入了
很遗憾NumberPicker没有提供修改字体颜色和字体大小的方法,不过我们可以继承NumberPicker实现需求,代码并不复杂,只是多写了几行代码,其他代码复制粘贴就好了。
package com.my.numberpickertest;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.NumberPicker;
public class MyNumberPicker extends NumberPicker {
public MyNumberPicker(Context context) {
super(context);
}
public MyNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyNumberPicker(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 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);
}
/**
* 修改字的大小和颜色
*/
private void updateView(View view){
if( view instanceof EditText){
EditText editText = (EditText) view;
editText.setTextColor(Color.parseColor("#00ff00")); //修改字的颜色
editText.setTextSize(30);//修改字的大小
}
}
}
然后在xml中使用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.my.numberpickertest.MyNumberPicker
android:id="@+id/numberPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
RelativeLayout>
我们需要通过反射设置分割线的颜色,代码还是在继承的类中修改
package com.my.numberpickertest;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.NumberPicker;
import java.lang.reflect.Field;
public class MyNumberPicker extends NumberPicker {
public MyNumberPicker(Context context) {
super(context);
}
public MyNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyNumberPicker(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 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);
}
/**
* 修改字的大小和颜色
*/
private void updateView(View view){
if( view instanceof EditText){
EditText editText = (EditText) view;
editText.setTextColor(Color.parseColor("#00ff00")); //修改字的颜色
editText.setTextSize(30);//修改字的大小
}
}
/**
* 修改分割线的颜色
*/
public void setNumberPickerDividerColor(int color){
Field[] pickerFields = NumberPicker.class.getDeclaredFields();
for (Field pf : pickerFields){
if(pf.getName().equals("mSelectionDivider")){ //找到mSelectionDivider
pf.setAccessible(true);
//设置分割线的颜色
try {
pf.set(this, new ColorDrawable(color));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
使用
mMyNumberPicker = (MyNumberPicker) findViewById(R.id.numberPicker);
mMyNumberPicker.setMinValue(0); //设置最小值
mMyNumberPicker.setMaxValue(10); //设置最大值
mMyNumberPicker.setValue(0); //设置当前值
//设置分割线的颜色 设置0可以让颜色变透明
mMyNumberPicker.setNumberPickerDividerColor(0xffff0000);
隐藏分割线就是设置分割线的颜色为透明
mMyNumberPicker.setNumberPickerDividerColor(0);
设置文字颜色、文字大小、分割线颜色的实例代码
有兴趣的朋友可以读一读另一篇文章NumberPicker实践