本文主要讲的是如何好看的添加车牌号,我们都知道号是由省份缩写+城市字母+5位数字或字母总共七位组成的。例如:赣A12cd5。
由于最近公司有个有关停车场管理系统的项目,里面有个用户添加绑定车牌号的功能。原理就是通过自定义滚轮选择器和自定义编辑框(之前我有写:地址)。
自定义滚轮选择器,我这里主要有三种:时间选择器(六种格式),单选选择器,多项选择器(三级联动,二级联动)。
选择器工具类:
public class pickerViewUtil<T> {
/**
* 时间选择回调
*/
public interface TimerPickerCallBack {
void onTimeSelect(String date);
}
/**
* 弹出时间选择
*
* @param context
* @param type TimerPickerView 中定义的 选择时间类型
* @param format 时间格式化
* @param callBack 时间选择回调
*/
public static void alertTimerPicker(Context context, TimePickerView.Type type, final String format,
final TimerPickerCallBack callBack) {
TimePickerView pvTime = new TimePickerView(context, type);
//控制时间范围
// Calendar calendar = Calendar.getInstance();
// pvTime.setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR));
pvTime.setTime(new Date());
pvTime.setCyclic(false);
/*点击其他部位弹框消失*/
pvTime.setCancelable(true);
/*设置顶部标题*/
pvTime.setTitle("请选择时间");
//时间选择后回调
pvTime.setOnTimeSelectListener(new TimePickerView.OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date) {
// tvTime.setText(getTime(date));
SimpleDateFormat sdf = new SimpleDateFormat(format);
callBack.onTimeSelect(sdf.format(date));
}
});
/*时间选择器字体大小*/
pvTime.setTextSize(16);
//弹出时间选择器
pvTime.show();
}
/* -------------------------- 单项选择 -------------------------------------------*/
/**
* 底部滚轮点击事件回调
*/
public interface OnWheelViewClick {
void onClick(View view, int postion);
}
/**
* 弹出底部滚轮选择
*
* @param title 标题
* @param context
* @param list 传进来的数据
* @param click
*/
public static void alertBottomWheelOption(final Context context, String title, ArrayList<?> list, final OnWheelViewClick click) {
final PopupWindow popupWindow = new PopupWindow();
View view = LayoutInflater.from(context).inflate(R.layout.layout_bottom_wheel_option, null);
TextView tv_confirm = (TextView) view.findViewById(R.id.btnSubmit);
TextView tv_title = (TextView) view.findViewById(R.id.tvTitle);
final WheelView wv_option = (WheelView) view.findViewById(R.id.wv_option);
wv_option.setAdapter(new ArrayWheelAdapter(list));
wv_option.setCyclic(false);
/*设置选项的单位*/
// wv_option.setLabel("呵呵");
/*设置默认位置*/
wv_option.setCurrentItem(0);
/*设置字体大小*/
wv_option.setTextSize(21);
/*确认*/
tv_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
backgroundAlpaha((Activity) context, 1);
click.onClick(view, wv_option.getCurrentItem());
}
});
/*设置标题*/
tv_title.setText(title);
/*取消*/
view.findViewById(R.id.btnCancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
backgroundAlpaha((Activity) context, 1);
}
});
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int top = view.findViewById(R.id.ll_container).getTop();
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
int y = (int) motionEvent.getY();
if (y < top) {
popupWindow.dismiss();
backgroundAlpaha((Activity) context, 1);
}
}
return true;
}
});
popupWindow.setAnimationStyle(R.style.PopupAnimation); // 设置弹出动画
popupWindow.setContentView(view);
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
ColorDrawable colorDrawable = new ColorDrawable(context.getResources()
.getColor(R.color.transparent));
popupWindow.setBackgroundDrawable(colorDrawable);// 如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
popupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
backgroundAlpaha((Activity) context, 0.5f);
popupWindow.showAtLocation(((ViewGroup) ((Activity) context).findViewById(android.R.id.content)).getChildAt(0), Gravity.CENTER, 0, 0);
}
/* -------------------------------- 三级别选择器 ------------------------------------------------*/
public void optionPicker(Context context, String title, OptionsPickerView.OnOptionsSelectListener listener,
ArrayList<T> options1Items, ArrayList<ArrayList<T>> options2Items,
ArrayList<ArrayList<ArrayList<T>>> options3Items, String[] labels) {
//选项选择器
OptionsPickerView pvOptions = new OptionsPickerView(context);
/*点击其他部位弹框消失*/
pvOptions.setCancelable(true);
//三级联动效果 当为true的时候:次目录会随着上级目录的变动而变动
pvOptions.setPicker(options1Items, options2Items, options3Items, true);
/*设置选择的三级单位,就是在滚轮旁再添加的字体*/
if (labels.length == 1) {
pvOptions.setLabels(labels[0]);
} else if (labels.length == 2) {
pvOptions.setLabels(labels[0], labels[1]);
} else if (labels.length == 3) {
pvOptions.setLabels(labels[0], labels[1], labels[2]);
}
/*选择标题*/
pvOptions.setTitle(title);
pvOptions.setCyclic(false, false, false);
//设置默认选中的三级项目
pvOptions.setSelectOptions(1, 1, 1);
/*设置文字的大小 有个小bug:只有字体大于22第一个item的线才不会错位*/
pvOptions.setTextSize(22);
/*监听确定选择按钮*/
pvOptions.setOnoptionsSelectListener(listener);
pvOptions.show();
}
/**
* 二级别选择器
*
* @param title 标题
* @param listener 结果监听者
* @param linkOne 一级目录
* @param linkTwo 二级目录
* @param labels 设置选项的单位
* @param linkage 是否联动
*/
public void twoPicker(Context context, String title,
OptionsPickerView.OnOptionsSelectListener listener, ArrayList<String> linkOne,
ArrayList<ArrayList<String>> linkTwo, String[] labels, boolean linkage) {
//选项选择器
OptionsPickerView pvOptions = new OptionsPickerView(context);
/*点击其他部位弹框消失*/
pvOptions.setCancelable(true);
//二级联动效果 当为true的时候:次目录会随着上级目录的变动而变动
pvOptions.setPicker(linkOne, linkTwo, linkage);
/*设置选择的三级单位,就是在滚轮旁再添加的字体*/
if (labels.length == 1) {
pvOptions.setLabels(labels[0]);
} else if (labels.length == 2) {
pvOptions.setLabels(labels[0], labels[1]);
}
/*选择标题*/
pvOptions.setTitle(title);
pvOptions.setCyclic(false, false);
//设置默认选中二级目录
pvOptions.setSelectOptions(0, 0);
/*设置文字的大小 有个小bug:只有字体大于22第一个item的线才不会错位*/
pvOptions.setTextSize(22);
/*监听确定选择按钮*/
pvOptions.setOnoptionsSelectListener(listener);
pvOptions.show();
}
}
车牌号录入的主类:
public class PlateNumActivity extends BaseActivity implements View.OnClickListener {
String tag = "PlateNumActivity";
private GridPasswordView gpvOne, gpvTwo;
private TextView oneOne, oneTwo, Two, result;
private ArrayList<String> privince = new ArrayList<>();
private ArrayList<ArrayList<String>> city = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_platenum);
intView();
}
private void intView() {
findViewById(R.id.platenum_btn).setOnClickListener(this);
findViewById(R.id.back_platenum).setOnClickListener(this);
gpvOne = (GridPasswordView) findViewById(R.id.platenum_gpvone);
gpvTwo = (GridPasswordView) findViewById(R.id.platenum_gpvtwo);
oneOne = (TextView) findViewById(R.id.platenum_oneone);
oneTwo = (TextView) findViewById(R.id.platenum_onetwo);
Two = (TextView) findViewById(R.id.platenum_two);
result = (TextView) findViewById(R.id.platenum_result);
oneOne.setOnClickListener(this);
oneTwo.setOnClickListener(this);
Two.setOnClickListener(this);
/*设置成明码状态,默认是暗码所以要切换状态.或者直接设置setPasswordVisibility*/
// gpvOne.togglePasswordVisibility();
gpvTwo.togglePasswordVisibility();
gpvOne.setPasswordVisibility(true);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back_platenum:
finish();
break;
case R.id.platenum_btn:
result.setText("车牌一:" + oneOne.getText() + oneTwo.getText() + gpvOne.getPassWord() + "\n" +
"车牌二:" + Two.getText() + gpvTwo.getPassWord());
break;
case R.id.platenum_oneone:
ChoicePrivince();
break;
case R.id.platenum_onetwo:
ChoiceCity();
break;
case R.id.platenum_two:
ChoicePrivinceCity();
break;
}
}
/*设置单级联动城市*/
private void ChoiceCity() {
privince = DataPlateNum.getcity();
pickerViewUtil.alertBottomWheelOption(this, "选择城市字母", privince, new pickerViewUtil.OnWheelViewClick() {
@Override
public void onClick(View view, int postion) {
oneTwo.setText(privince.get(postion));
}
});
}
/*设置单级联动省份*/
private void ChoicePrivince() {
privince = DataPlateNum.getPrivince();
pickerViewUtil.alertBottomWheelOption(this, "选择省份缩写", privince, new pickerViewUtil.OnWheelViewClick() {
@Override
public void onClick(View view, int postion) {
oneOne.setText(privince.get(postion));
}
});
}
/*通过二级联动选车牌*/
private void ChoicePrivinceCity() {
DataPlateNum.initTwo(privince, city);
String[] labels = {};
new pickerViewUtil().twoPicker(this, "请选择车牌归属地", new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3) {
// String tv = privince.get(options1)+ city.get(options1).get(option2)
/*因为我只加了两个二级参数所以第二options1设为0(我未设置联动所以默认都是0中的) */
Two.setText(privince.get(options1) + city.get(0).get(option2));
}
}, privince, city, labels, false);
}
}
数据bean类:
public class DataPlateNum {
public static void initTwo(ArrayList<String> one, ArrayList<ArrayList<String>> two) {
setPrivince(one);
two.add(getcity());
two.add(getPrivince());
}
/*设置省份缩写的集合*/
public static void setPrivince(ArrayList<String> a) {
a.add("赣");
a.add("粤");
a.add("京");
a.add("沪");
a.add("鄂");
a.add("湘");
a.add("川");
a.add("渝");
a.add("闽");
a.add("晋");
a.add("黑");
a.add("津");
a.add("浙");
a.add("豫");
a.add("贵");
a.add("青");
a.add("琼");
a.add("宁");
a.add("蒙");
a.add("吉");
a.add("冀");
a.add("苏");
a.add("皖");
a.add("桂");
a.add("云");
a.add("陕");
a.add("甘");
a.add("藏");
a.add("新");
a.add("辽");
a.add("鲁");
}
/*返回城市字母缩写*/
public static ArrayList<String> getcity() {
ArrayList<String> c = new ArrayList();
c.add("A");
c.add("B");
c.add("C");
c.add("D");
c.add("E");
c.add("F");
c.add("G");
c.add("H");
c.add("I");
c.add("J");
c.add("K");
c.add("L");
c.add("M");
c.add("N");
c.add("O");
c.add("P");
c.add("Q");
c.add("R");
c.add("S");
c.add("T");
c.add("U");
c.add("V");
c.add("W");
c.add("X");
c.add("Y");
c.add("Z");
return c;
}
/*返回省份缩写的集合*/
public static ArrayList<String> getPrivince() {
ArrayList<String> a = new ArrayList();
a.add("赣");
a.add("粤");
a.add("京");
a.add("沪");
a.add("鄂");
a.add("湘");
a.add("川");
a.add("渝");
a.add("闽");
a.add("晋");
a.add("黑");
a.add("津");
a.add("浙");
a.add("豫");
a.add("贵");
a.add("青");
a.add("琼");
a.add("宁");
a.add("蒙");
a.add("吉");
a.add("冀");
a.add("苏");
a.add("皖");
a.add("桂");
a.add("云");
a.add("陕");
a.add("甘");
a.add("藏");
a.add("新");
a.add("辽");
a.add("鲁");
return a;
}
}
效果图: