最近在做項(xiàng)目的時(shí)候,有這樣一個(gè)需求,要實(shí)現(xiàn)取件碼的輸入,效果圖如下:

要實(shí)現(xiàn)效果
看到這個(gè)圖,立馬想到,這個(gè)類似于支付寶、微信的密碼輸入框。
實(shí)現(xiàn)方法總結(jié):
一、直接寫四個(gè)EditText,然后對(duì)其設(shè)置maxLength為1。
<EditText
android:id="@+id/et_inputPickupNum1"
android:layout_width="40dp"
android:layout_height="40dp"
android:inputType="number"
android:gravity="center"
android:maxLength="1"
android:background="#0000ff"/>
在代碼中,對(duì)其設(shè)置監(jiān)聽(tīng)事件,事件主要功能如下:
1)當(dāng)有輸入后,立馬使其失去焦點(diǎn),同時(shí)讓下一個(gè)EditText獲取焦點(diǎn)。
2)當(dāng)刪除的時(shí)候,使其使其失去焦點(diǎn),同時(shí)讓前一個(gè)獲取焦點(diǎn)。
etPickupNum2.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!TextUtils.isEmpty(s.toString().trim())){
etPickupNum2.clearFocus();
etPickupNum2.setFocusable(false);
etPickupNum3.setFocusable(true);
etPickupNum3.setFocusableInTouchMode(true);
etPickupNum3.requestFocus();
}else{
etPickupNum2.clearFocus();
etPickupNum1.setFocusable(true);
etPickupNum1.setFocusableInTouchMode(true);
etPickupNum1.requestFocus();
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
不過(guò),這種實(shí)現(xiàn)方式代碼量大,可擴(kuò)展性差。這種實(shí)現(xiàn)方式,還存在一個(gè)問(wèn)題,就是刪除一個(gè)后,光標(biāo)跳到前一個(gè)去了,繼續(xù)輸入還得點(diǎn)一下EditText。
二、在同一個(gè)布局容器中添加四個(gè)TextView,用于顯示輸入后的文字。同時(shí)在這個(gè)布局容器上邊添加一個(gè)背景透明的、隱藏了光標(biāo)、字體也是透明的EditText。在代碼中,對(duì)EditText設(shè)置輸入監(jiān)聽(tīng)事件。
1)xml文件中:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_inputPickupNum1"
android:layout_width="40dp"
android:layout_height="40dp"
android:textColor="#ffffff"
android:background="#0000ff"/>
<View
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
.......
</LinearLayout>
<EditText
android:id="@+id/et_inputPickupNum"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxLength="4"
android:background="@android:color/transparent"
android:textColor="@android:color/transparent"
<!--cursorVisible設(shè)置為false,表示隱藏光標(biāo)-->
android:cursorVisible="false"/>
</RelativeLayout>
2)代碼中:
etnum.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//numList是一個(gè)存放四個(gè)TextView的集合
for (TextView tvNum:numList){
tvNum.setText("");
}
String str = s.toString().trim();
if (!TextUtils.isEmpty(str)){
for(int i = 0;i < str.length();i++){
numList.get(i).setText(str.substring(i,i+1));
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
這種和第一種比較,就是不用考慮焦點(diǎn)的得失。
三、自定義View。實(shí)現(xiàn)思路是:
1) 定義內(nèi)容背景顏色、間距、間距顏色、字體顏色等屬性。
2)在xml中設(shè)置這些屬性值。
3)寫一個(gè)類繼承EditText,獲取上邊屬性值,并且實(shí)現(xiàn)輸入事件監(jiān)聽(tīng)。
4)做全局配置:讓該EditText獲取焦點(diǎn),再設(shè)置最大長(zhǎng)度。設(shè)置字體顏色為透明,隱藏光標(biāo)。
private void initView() {
setFocusable(true);
setFocusableInTouchMode(true);
this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
this.setTextColor(Color.TRANSPARENT);
this.setGravity(Gravity.CENTER_VERTICAL);
if(mPaint == null){
mPaint = new Paint();
}
mPaint.setTextSize(textSize);
mPaint.setColor(spacingColor);
if (mBound == null){
mBound = new Rect();
}
}
5)設(shè)置背景,實(shí)現(xiàn)四個(gè)顯示框,以及中間間距。
private void drawBackground(Canvas canvas) {
//contentWidth為顯示框?qū)挾?,spacingWidth為間距寬度,maxLength為最大長(zhǎng)度
contentWidth = (getWidth() - spacingWidth*(maxLength-1))/maxLength;
for (int i = 0;i < maxLength;i++){
//contentColor為文本框背景顏色
mPaint.setColor(contentColor);
Rect rect = new Rect(i*(spacingWidth + contentWidth),0,i*(spacingWidth + contentWidth) + contentWidth,getHeight());
canvas.drawRect(rect,mPaint);
if (i != maxLength -1){
//spacingColor為間距的背景顏色
mPaint.setColor(spacingColor);
Rect spacingRect = new Rect(i*(spacingWidth + contentWidth) + contentWidth,0,(i+1)*(spacingWidth + contentWidth),getHeight());
canvas.drawRect(spacingRect,mPaint);
}
}
}
6)繪制文字。
//content用于記錄當(dāng)前輸入字符串
mPaint.getTextBounds(content,0,content.length(),mBound);
mPaint.setColor(textColor);
for (int i = 0;i < content.length();i++){
canvas.drawText(content.substring(i,i+1),i*(spacingWidth + contentWidth),getHeight()/2 + mBound.height()/2,mPaint);
}