需求,最大9999900,最小100,100的整数倍,个人感觉通过文本框方式去判断和限制用户输入不是一个很友好的方式,所以通过选择器的方式去填写数据
先上图
因为是100的整数倍且最小为100,那么最后两位固定为00,当全部数据选择为0时,默认为100.
上图实现方式为 NumberPicker+BottomSheetDialog 实现
其中 NumberPicker 在 BottomSheetDialog 的布局文件中,所以通过自定义的布局文件可以实现 各种选择器的效果,本文只介绍数字选择器,其他选择器自己去实现吧,实现过程千篇一律
1.首先添加 底部弹窗依赖
implementation 'com.android.support:design:28.0.0'
2.设置自定义布局
item_choick.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#777777"
xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/item_radius"
xmlns:android="http://schemas.android.com/apk/res/android" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_marginTop="5dp"
android:layout_height="32dp">
<TextView
android:id="@+id/tv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="23dp"
android:layout_marginLeft="10dp"
android:text="取消"/>
<TextView
android:id="@+id/tv_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="23dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:text="确定"/>
</RelativeLayout>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="当前金额:100元"
android:textSize="24dp"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/np_1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="百万"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="十万"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_3"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="万"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_4"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="千"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_5"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="百"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_6"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="十"
android:gravity="center"
android:layout_height="match_parent"/>
<NumberPicker
android:id="@+id/np_7"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="个"
android:gravity="center"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
item_radius.xml 用于设置弹出框为圆角样式
该布局文件 位于 drawable 下
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- solid 设置stroke设置的边框以内的颜色 -->
<solid android:color="#ffffff"/>
<!-- stroke主要设置组件的边框。width为边框宽度,color为边框颜色 -->
<stroke android:width="3dp" android:color="#777777" />
<!-- corners 设置边框四角弧度 -->
<corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
<!-- padding主要设置组件里内容距离组件内边框的间距 -->
<padding android:left="3dp" android:top="3dp" android:right="3dp" />
</shape>
3.设置自定义弹框类
代码
//底部数字选择弹窗
public class NumberChoiceWindow extends BottomSheetDialog {
private NumberPicker np_1,np_2,np_3,np_4,np_5,np_6,np_7;
private int np1 = 0,np2 = 0,np3 = 0,np4 = 0,np5 = 1,np6 = 0,np7 = 0;
private final TextView tv;
public static String num = "100";
@SuppressLint("ClickableViewAccessibility")
public NumberChoiceWindow(@NonNull Context context, View view) {
super(context);
setContentView(view);
/* View root=this.getDelegate().findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior behavior=BottomSheetBehavior.from(root);
behavior.setHideable(false);*/
tv = findViewById(R.id.tv);
np_1 = findViewById(R.id.np_1);
np_2 = findViewById(R.id.np_2);
np_3 = findViewById(R.id.np_3);
np_4 = findViewById(R.id.np_4);
np_5 = findViewById(R.id.np_5);
np_6 = findViewById(R.id.np_6);
np_7 = findViewById(R.id.np_7);
init(np_1);
init(np_2);
init(np_3);
init(np_4);
init(np_5);
init(np_6);
init(np_7);
initData();
}
private void init(NumberPicker np) {
np.setMaxValue(9);
np.setMinValue(0);
np.setValue(0);
np_5.setMaxValue(9);
np_5.setMinValue(0);
np_5.setValue(np5);
np_6.setMaxValue(0);
np_6.setMinValue(0);
np_6.setValue(0);
np_7.setMaxValue(0);
np_7.setMinValue(0);
np_7.setValue(0);
//设置为对当前值不可编辑
np.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
// minutePicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);
//这里设置为不循环显示,默认值为true
np.setWrapSelectorWheel(false);
np_1.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np1 = i1;
getNum();
}
});
np_2.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np2 = i1;
getNum();
}
});
np_3.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np3 = i1;
getNum();
}
});
np_4.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np4 = i1;
getNum();
}
});
np_5.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np5 = i1;
getNum();
}
});
np_6.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np6 = i1;
getNum();
}
});
np_7.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
np7 = i1;
getNum();
}
});
}
private void getNum() {
String str_np1 = String.valueOf(np1);
String str_np2 = String.valueOf(np2);
String str_np3 = String.valueOf(np3);
String str_np4 = String.valueOf(np4);
String str_np5 = String.valueOf(np5);
String str_np6 = String.valueOf(np6);
String str_np7 = String.valueOf(np7);
if (str_np1.equals("0") && str_np2.equals("0") && str_np3.equals("0") && str_np4.equals("0") &&
str_np5.equals("0")) {
num = "100";
}else if(str_np1.equals("0") && str_np2.equals("0") && str_np3.equals("0") && str_np4.equals("0") ){
num = str_np5 + str_np6 + str_np7;
}else if(str_np1.equals("0") && str_np2.equals("0") && str_np3.equals("0") ){
num = str_np4 + str_np5 + str_np6 + str_np7;
}else if(str_np1.equals("0") && str_np2.equals("0")){
num = str_np3 + str_np4 + str_np5 + str_np6 + str_np7;
}else if(str_np1.equals("0")){
num = str_np2 + str_np3 + str_np4 + str_np5 + str_np6 + str_np7;
}else {
num = str_np1 + str_np2 + str_np3 + str_np4 + str_np5 + str_np6 + str_np7;
}
tv.setText("当前金额:"+num+"元");
}
private void initData() {
}
BottomSheetBehavior bottomSheetBehavior;
public void setmBottomSheetCallback(View sheetView) {
if (bottomSheetBehavior == null) {
bottomSheetBehavior = BottomSheetBehavior.from(sheetView);
}
bottomSheetBehavior.setBottomSheetCallback(mBottomSheetCallback);
}
//此部分为禁止该弹窗可滑动
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback
= new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet,
@BottomSheetBehavior.State int newState) {
if (newState == BottomSheetBehavior.STATE_DRAGGING) {//判断为向下拖动行为时,则强制设定状态为展开
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );
}
if (newState == BottomSheetBehavior.STATE_SETTLING ){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );
}
if (newState == BottomSheetBehavior.STATE_EXPANDED ){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );
}
if (newState == BottomSheetBehavior.STATE_COLLAPSED ){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );
}
if (newState == BottomSheetBehavior.STATE_HIDDEN ){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// LogUtil.e(TAG, "onSlide——>" + slideOffset);
}
};
}
4.在Activity中调用
代码
private void choice() {
View view = LayoutInflater.from(this).inflate(R.layout.item_choick,null,false);
final NumberChoiceWindow testPopWindow = new NumberChoiceWindow(MainActivity.this,view);
testPopWindow.setmBottomSheetCallback((View) view.getParent());
testPopWindow.show();
TextView tv_cancel = view.findViewById(R.id.tv_cancel);
TextView tv_ok = view.findViewById(R.id.tv_ok);
tv_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
testPopWindow.dismiss();
}
});
tv_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tv_choice.setText(NumberChoiceWindow.num);//为当前页面的控件设置数据
testPopWindow.dismiss();
}
});
以上就是实现方式,思路并不复杂,也尽量详细了,就差直接上源码了,也是为了以后自己在使用到还能看明白。。。