本文来自阿钟的投稿,全文阅读大约十分钟
为了便于用户快捷的输入车牌号码便需要自定义个车牌键盘,而不是使用系统的键盘输入,上效果图:
横屏效果
竖屏效果
一、首先我们要来分析一下需要做哪些东西
默认展示车牌的省份简称
特殊车牌(使、领、警、港、澳)
删除键
切换为数字和字母按键
车牌号中是没有I、O
字母的(容易与1、0)分混淆,故不需要这两个按键
I、O
这两个按键的位置正好使用学、挂
来填充
二、根据效果图可以看出键盘就是个网格列表,所以很容易就想到使用`RecyclerView`来实现即简单又高效
创建个LicensePlateView
类继承自LinearLayout
我们需要定义我们的按键资源
在`string.xml`文件中定义我们的资源
简称
2<item>京item> 3<item>沪item> 4<item>浙item> 5<item>苏item> 6<item>粤item> 7<item>鲁item> 8<item>晋item> 9<item>冀item> 10<item>豫item> 11<item>川item> 12<item>渝item> 13<item>辽item> 14<item>吉item> 15<item>黑item> 16<item>皖item> 17<item>鄂item> 18<item>湘item> 19<item>赣item> 20<item>闽item> 21<item>陕item> 22<item>甘item> 23<item>宁item> 24<item>蒙item> 25<item>津item> 26<item>贵item> 27<item>云item> 28<item>桂item> 29<item>琼item> 30<item>青item> 31<item>Delitem> 32<item>item> 33<item>新item> 34<item>藏item> 35<item>使item> 36<item>领item> 37<item>警item> 38<item>港item> 39<item>澳item> 40<item>ABC\n123item> 41array>1<arrayname="province">
数字、字母
2<item>"0"item> 3<item>"1"item> 4<item>"2"item> 5<item>"3"item> 6<item>"4"item> 7<item>"5"item> 8<item>"6"item> 9<item>"7"item> 10<item>"8"item> 11<item>"9"item> 12<item>Qitem> 13<item>Witem> 14<item>Eitem> 15<item>Ritem> 16<item>Titem> 17<item>Yitem> 18<item>Uitem> 19<item>学item> 20<item>挂item> 21<item>Pitem> 22<item>Aitem> 23<item>Sitem> 24<item>Ditem> 25<item>Fitem> 26<item>Gitem> 27<item>Hitem> 28<item>Jitem> 29<item>Kitem> 30<item>Litem> 31<item>Delitem> 32<item>item> 33<item>Zitem> 34<item>Xitem> 35<item>Citem> 36<item>Vitem> 37<item>Bitem> 38<item>Nitem> 39<item>Mitem> 40<item>省item> 41array>1<arrayname="nums">
`这里需要特别注意,定义数字的时候需要给它加上" ",否则代码获取的为null`
键盘的最后一行第一个是需要空开来的,所以直接使用个空字符串占位即可。
三、 编写每个按键的布局
2<LinearLayoutxmlns:android="/apk/res/android" 3android:layout_width="match_parent" 4android:layout_height="35dp" 5android:background="@drawable/sel_white_radius_2" 6android:gravity="center"> 7<TextView 8android:id="@+id/tv_key" 9android:layout_width="wrap_content"10android:layout_height="match_parent"11android:gravity="center"12android:lineSpacingMultiplier="0.8"13android:text="京"14android:textColor="#333333"15android:textSize="16sp"/> 16LinearLayout>1<?xml version="1.0"encoding="utf-8"?>
四、通过代码动态创建一个`RecyclerView`
LicensePlateView
2/** 3*车牌简称 4*/ 5privateListprovinceList=newArrayList<>(); 6/** 7*0~9,A~Z(车牌里没有I、O字母) 8*/ 9privateListnumList=newArrayList<>(); 10/** 11*键盘的背景颜色 12*/ 13privatefinalintbackgroundColor=Color.parseColor("#e9e9e9"); 14/** 15*键盘文字颜色 16*/ 17privatefinalintkeyTextColor=Color.parseColor("#333333"); 18/** 19*键盘列数 20*/ 21privatefinalintspanCount=10; 22/** 23*键盘键的间隔 24*/ 25privatefinalintkeyButtonMargin=15; 26/** 27*键盘上下左右的边距 28*/ 29privatefinalintkeyboardPadding=10; 30/** 31*按键点击回调 32*/ 33privateOnKeyClickListeneronKeyClickListener; 34privateKeyAdapterkeyAdapter; 35publicLicensePlateView(Contextcontext){36super(context); 37init(context); 38} 39 40publicLicensePlateView(Contextcontext,@NullableAttributeSetattrs){41super(context,attrs); 42init(context); 43} 44privatevoidinit(Contextcontext){45setOrientation(LinearLayout.VERTICAL); 46setBackgroundColor(backgroundColor); 47initKeys(); 48RecyclerViewrecyclerView=newRecyclerView(context); 49recyclerView.setOverScrollMode(OVER_SCROLL_NEVER); 50recyclerView.setLayoutManager(newGridLayoutManager(context,spanCount)); 51recyclerView.addItemDecoration(newRecycleGridDivider(keyButtonMargin)); 52intpadding=dip2px(context,keyboardPadding); 53recyclerView.setPadding(padding,padding,padding,padding); 54addView(recyclerView); 55keyAdapter=newKeyAdapter(this); 56recyclerView.setAdapter(keyAdapter); 57keyAdapter.setNewData(provinceList); 58} 59/** 60*初始化按键 61*/ 62privatevoidinitKeys(){63String[]province=getResources().getStringArray(R.array.province); 64String[]num=getResources().getStringArray(R.array.nums); 65Collections.addAll(provinceList,province); 66Collections.addAll(numList,num); 67} 68/** 69*按键点击事件 70*/ 71@Override 72publicvoidonClick(Viewv){73TextViewtvKey=v.findViewById(R.id.tv_key); 74Stringkey=tvKey.getText().toString(); 75if(key.equals("ABC\n123")){76//键盘切换 77keyAdapter.setNewData(numList); 78return; 79}elseif(key.equals("省")){80keyAdapter.setNewData(provinceList); 81return; 82} 83if(onKeyClickListener!=null){84onKeyClickListener.onKeyClick(key); 85} 86} 87privateclassKeyAdapterextendsRecyclerView.Adapter{88privateListlist=newArrayList<>(); 89privateOnClickListenerlistener; 90publicKeyAdapter(OnClickListenerlistener){91this.listener=listener; 92} 93@NonNull 94@Override 95publicKeyAdapter.KeyViewHolderonCreateViewHolder(@NonNullViewGroupparent,intviewType){96Viewview=LayoutInflater.from(parent.getContext()).inflate(R.layout.item_key,parent,false); 97returnnewKeyViewHolder(view); 98} 99100@Override101publicvoidonBindViewHolder(@NonNullKeyAdapter.KeyViewHolderholder,intposition){102Stringkey=list.get(position);103holder.tvKey.setText(key);104holder.itemView.setOnClickListener(listener);105if(TextUtils.isEmpty(key)){106holder.itemView.setBackgroundResource(0);107//键盘类型切换按键108}elseif(key.equals("ABC\n123")||key.equals("省")){109holder.tvKey.setTextSize(10);110holder.itemView.setBackgroundResource(R.drawable.sel_blue_radius_2);111holder.tvKey.setTextColor(Color.WHITE);112}else{113holder.tvKey.setTextSize(12);114holder.itemView.setBackgroundResource(R.drawable.sel_white_radius_2);115holder.tvKey.setTextColor(keyTextColor);116}117}118@Override119publicintgetItemCount(){120returnlist.size();121}122publicvoidsetNewData(Listlist){123this.list.clear();124this.list.addAll(list);125notifyDataSetChanged();126}127privateclassKeyViewHolderextendsRecyclerView.ViewHolder{128privateTextViewtvKey;129publicKeyViewHolder(@NonNullViewitemView){130super(itemView);131tvKey=itemView.findViewById(R.id.tv_key);132}133}134}135publicclassRecycleGridDividerextendsRecyclerView.ItemDecoration{136/**137*分割线宽度138*/139privateintspace;140141publicRecycleGridDivider(intspace){142this.space=space;143}144@Override145publicvoidgetItemOffsets(RectoutRect,Viewview,RecyclerViewparent,RecyclerView.Statestate){146GridLayoutManagermanager=(GridLayoutManager)parent.getLayoutManager();147intspan=manager.getSpanCount();148//为了Item大小均匀,将设定分割线平均分给左右两边Item各一半149intoffset=space/2;150//得到View的位置151intchildPosition=parent.getChildAdapterPosition(view);152//第一排,顶部不画153if(childPosition154//最左边的,左边不画155if(childPosition%span==0){156outRect.set(0,0,offset,0);157//最右边,右边不画158}elseif(childPosition%span==span-1){159outRect.set(offset,0,0,0);160}else{161outRect.set(offset,0,offset,0);162}163}else{164//上下的分割线,就从第二排开始,每个区域的顶部直接添加设定大小,不用再均分了165if(childPosition%span==0){166outRect.set(0,space,offset,0);167}elseif(childPosition%span==span-1){168outRect.set(offset,space,0,0);169}else{170outRect.set(offset,space,offset,0);171}172}173}174}175/**176*设置按键点击事件177*/178publicvoidsetOnKeyClickListener(OnKeyClickListenerlistener){179this.onKeyClickListener=listener;180}181publicinterfaceOnKeyClickListener{182voidonKeyClick(Stringkey);183}184/**185*根据手机的分辨率从dp的单位转成为px(像素)186*/187publicstaticintdip2px(Contextcontext,floatdpValue){188finalfloatscale=context.getResources().getDisplayMetrics().density;189return(int)(dpValue*scale+0.5f);190}191}1publicclassLicensePlateViewextendsLinearLayoutimplementsView.OnClickListener{
四、对于我们需要输入车牌的`EditText`,需要它禁止弹出系统键盘;设置如下:
2etPlate.setInputType(InputType.TYPE_NULL); 3etPlate.setKeyListener(null);1//禁止输入框弹出键盘
五、封装好后使用就很简单了
2plateView.setOnKeyClickListener(newLicensePlateView.OnKeyClickListener(){ 3@Override 4publicvoidonKeyClick(Stringkey){ 5Editableeditable=etPlate.getText(); 6intstart=etPlate.getSelectionStart(); 7if(key.equalsIgnoreCase("Del")){ 8if(editable.length()>0&&start>0){ 9editable.delete(start-1,start); 10} 11return; 12} 13editable.insert(start,key); 14} 15});1LicensePlateViewplateView=findViewById(R.id.plate_view);
总体来说这个View还是很简单的
Demo下载地址:
/download/a_zhon/11646110
推荐我的慕课网Android实战课程,助你暴力提升Android技术。
/class/390.html
我创建了一个关于Android的交流群,有兴趣可以加我微信我拉你
如果感觉现在的网络技术文章质量不高,苦于自己的Android技术无法得到明显的提升,感叹没有一帮好的学习伙伴及道友,那么我的知识星球可能就是一片净土,好的学习气氛,更好的技术资源与文章,自由且高效率,快来吧。