對與一些如:身份證、銀行卡等号碼型文本需要在EditText中輸入時,會有一些自動分割的需求。如四位加個空格或者”-“等。
下面的是一個簡單的自定義EditText的View,來監聽EditText的輸入變化,并根據設定的索引位置添加分隔符。
身份證格式的效果圖如下:
下面是繼承EditText的實作:
package com.example.admin.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
import com.example.admin.myapplication.R;
import java.util.ArrayList;
import java.util.List;
public class SpaceEditText extends EditText {
private String spaceChar = " ";
private String spaceIndex = "";
private List<Integer> indexList = new ArrayList<>();
public SpaceEditText(Context context) {
super(context);
}
public SpaceEditText(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SpaceEditText);
spaceChar = typedArray.getString(typedArray.getIndex(R.styleable.SpaceEditText_spaceChar));
spaceIndex = typedArray.getString(typedArray.getIndex(R.styleable.SpaceEditText_spaceIndex));
if (!TextUtils.isEmpty(spaceIndex)) {
String[] indexs = spaceIndex.split(",");
for (String str : indexs) {
indexList.add(Integer.parseInt(str));
}
}
System.out.println("spaceChar:" + spaceChar);
System.out.println("indexList:" + indexList);
editTextLintener();
}
public SpaceEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void editTextLintener() {
this.addTextChangedListener(new TextWatcher() {
private boolean isChange = false;
private int lastLength = 0;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
lastLength = s.length();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = s.length();
if (!isChange) {
int selectIndex = getSelectionEnd();
if (lastLength < length) {
isChange = true;
String str = addSpace(s.toString());
int changeIndex = selectIndex;
if (selectIndex > 0 && selectIndex < str.length() && str.charAt(selectIndex - 1) == spaceChar.charAt(0)) {
changeIndex = selectIndex + 1;
}
setText(str);
if (selectIndex < length) {
setSelection(changeIndex);
} else
setSelection(str.length());
} else {
isChange = true;
String currentStr = s.toString();
int changeIndex = selectIndex;
if (selectIndex > 0 && currentStr.charAt(selectIndex - 1) == spaceChar.charAt(0)) {
changeIndex = selectIndex - 1;
currentStr = currentStr.substring(0, selectIndex - 1) + currentStr.substring(selectIndex, currentStr.length());
}
String str = addSpace(currentStr);
setText(str);
if (selectIndex < length)
setSelection(changeIndex);
else
setSelection(str.length());
}
} else {
isChange = false;
}
}
private String addSpace(String currentText) {
currentText = currentText.toString().replace(spaceChar, "");
char[] charArray = currentText.toCharArray();
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < charArray.length; i++) {
if (indexList.contains(i)) {
sb.append(spaceChar);
}
sb.append(charArray[i]);
}
return sb.toString();
}
@Override
public void afterTextChanged(Editable s) {
if (!isChange) {
// 對回調方法進行調用,使監聽回調的地方得到目前文本框中格式化以後的字元串結果
if (listener != null) {
listener.afterTextChanged(s.toString().replace(spaceChar, ""));
}
}
}
});
}
private AfterTextChangedListener listener = null;
public void setAfterTextChangedListener(AfterTextChangedListener listener) {
this.listener = listener;
}
/**
* 定義一個回調監聽接口,在完成輸入時傳回格式化好的輸入文本
*/
public interface AfterTextChangedListener {
public void afterTextChanged(String text);
}
}
attrs.xml中聲明SpaceEditText的屬性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SpaceEditText">
<attr name="spaceChar" format="string" />
<attr name="spaceIndex" format="string" />
</declare-styleable>
</resources>
布局檔案中使用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.admin.myapplication.EditTextActivity">
<com.example.admin.view.SpaceEditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:inputType="number"
android:layout_height="wrap_content"
app:spaceChar="-"
android:maxLength="22"
app:spaceIndex="4,8,13,18" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="送出"
android:padding="5dp"
android:id="@+id/submitBtn"
android:enabled="false"/>
</LinearLayout>
Activity中使用
package com.example.admin.myapplication;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.example.admin.view.SpaceEditText;
public class EditTextActivity extends ActionBarActivity {
private SpaceEditText editText;
private Button submitBtn;
private String textInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_text);
editText = (SpaceEditText) findViewById(R.id.editText);
submitBtn = (Button) findViewById(R.id.submitBtn);
editText.setAfterTextChangedListener(new SpaceEditText.AfterTextChangedListener() {
@Override
public void afterTextChanged(String text) {
if (text.length() == 18) {
submitBtn.setEnabled(true);
textInfo = text;
}
}
});
submitBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"text:"+textInfo,Toast.LENGTH_SHORT).show();
}
});
}
}