編集テキストにフォーマットの入力を許可させる方法
4digitnumber-4dignumber-4dignumber-4dignumber
コード
text.addTextChangedListener(new TextWatcher() {
int len = 0;
String string ;
@Override
public void afterTextChanged(Editable s) {
text.setOnKeyListener(new OnKeyListener()
{ public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_DEL)
{
}
else{
string = text.getText().toString();
len = string.length()+1;
if(len%5==0){text.append("-");}
}
return false; } });
}
});
追加時に問題なく機能しますが、削除または編集すると問題が発生します。
これはすべての削除/編集操作のソフト/ハードキーボードで正常に機能します。tx4 ur help ..
package com.and;
import Android.app.Activity;
import Android.app.AlertDialog;
import Android.inputmethodservice.KeyboardView;
import Android.os.Bundle;
import Android.telephony.PhoneNumberFormattingTextWatcher;
import Android.text.Editable;
import Android.text.Selection;
import Android.text.Spannable;
import Android.text.TextWatcher;
import Android.text.format.Formatter;
import Android.text.method.NumberKeyListener;
import Android.view.KeyEvent;
import Android.view.View;
import Android.view.View.OnKeyListener;
import Android.widget.EditText;
import Android.widget.Toast;
public class ccformat extends Activity {
String a;
int keyDel;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText text = (EditText) findViewById(com.and.R.id.editText1);
text.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
boolean flag = true;
String eachBlock[] = text.getText().toString().split("-");
for (int i = 0; i < eachBlock.length; i++) {
if (eachBlock[i].length() > 4) {
flag = false;
}
}
if (flag) {
text.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL)
keyDel = 1;
return false;
}
});
if (keyDel == 0) {
if (((text.getText().length() + 1) % 5) == 0) {
if (text.getText().toString().split("-").length <= 3) {
text.setText(text.getText() + "-");
text.setSelection(text.getText().length());
}
}
a = text.getText().toString();
} else {
a = text.getText().toString();
keyDel = 0;
}
} else {
text.setText(a);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
}
これは機能しています:
public class EditTextSample extends Activity {
// This regexp has to be improved, it does not detect case where you have
// more than 4 digits in a middle group like: 1234-12345-123
static final Pattern CODE_PATTERN = Pattern.compile("([0-9]{0,4})|([0-9]{4}-)+|([0-9]{4}-[0-9]{0,4})+");
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_text_sample);
final EditText editText = (EditText) findViewById(R.id.input);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
Log.w("", "input" + s.toString());
if (s.length() > 0 && !CODE_PATTERN.matcher(s).matches()) {
String input = s.toString();
String numbersOnly = keepNumbersOnly(input);
String code = formatNumbersAsCode(numbersOnly);
Log.w("", "numbersOnly" + numbersOnly);
Log.w("", "code" + code);
editText.removeTextChangedListener(this);
editText.setText(code);
// You could also remember the previous position of the cursor
editText.setSelection(code.length());
editText.addTextChangedListener(this);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
private String keepNumbersOnly(CharSequence s) {
return s.toString().replaceAll("[^0-9]", ""); // Should of course be more robust
}
private String formatNumbersAsCode(CharSequence s) {
int groupDigits = 0;
String tmp = "";
for (int i = 0; i < s.length(); ++i) {
tmp += s.charAt(i);
++groupDigits;
if (groupDigits == 4) {
tmp += "-";
groupDigits = 0;
}
}
return tmp;
}
});
}
}
私の場合、以下のコードは正常に動作しています。
editTextCreditCard.addTextChangedListener(new FourDigitCardFormatWatcher());
TextWatcherのカスタムクラスを追加します。
public class FourDigitCardFormatWatcher implements TextWatcher {
private static final char space = ' ';
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > 0 && (s.length() % 5) == 0) {
final char c = s.charAt(s.length() - 1);
if (space == c) {
s.delete(s.length() - 1, s.length());
}
}
if (s.length() > 0 && (s.length() % 5) == 0) {
char c = s.charAt(s.length() - 1);
if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(space)).length <= 3) {
s.insert(s.length() - 1, String.valueOf(space));
}
}
}
}
これがお役に立てば幸いです。
数値を視覚的にグループ化したいが、ダッシュを追加するEditText
の値を変更したくない場合は、このSpan
アプローチを使用できます:
_EditText editText = findViewById(R.id.editText);
editText.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) {}
@Override
public void afterTextChanged(Editable editable) {
Object[] paddingSpans = editable.getSpans(0, editable.length(), DashSpan.class);
for (Object span : paddingSpans) {
editable.removeSpan(span);
}
addSpans(editable);
}
private static final int GROUP_SIZE = 4;
private void addSpans(Editable editable) {
final int length = editable.length();
for (int i = 1; i * (GROUP_SIZE) < length; i++) {
int index = i * GROUP_SIZE;
editable.setSpan(new DashSpan(), index - 1, index,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
});
_
DashSpan
クラスは次のようになります。
_/**
* A {@link ReplacementSpan} used for spacing in {@link Android.widget.EditText}
* to space things out. Adds '-'s
*/
public class DashSpan extends ReplacementSpan {
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
float padding = Paint.measureText("-", 0, 1);
float textSize = Paint.measureText(text, start, end);
return (int) (padding + textSize);
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
int bottom, @NonNull Paint paint) {
canvas.drawText(text.subSequence(start, end) + "-", x, y, Paint);
}
}
_
このように、ダッシュを使用して視覚的にグループ化しますが、getText()
はグループ化せずにテキストを返します。
数値のみを強制するには、属性_Android:digits="0123456789"
_および_Android:inputType="number"
_をEditText
に追加できます。
このソリューションは this ライブラリのコードに基づいています。
以下は、カードの詳細をXXXX XXXX XXXX XXXXの形式で表示するために使用されるフォーマット正規表現です。
etCreditCardNumber.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) {
etCreditCardNumber.setFloatingLabel(MaterialEditText.FLOATING_LABEL_HIGHLIGHT);
String initial = s.toString();
// remove all non-digits characters
String processed = initial.replaceAll("\\D", "");
// insert a space after all groups of 4 digits that are followed by another digit
processed = processed.replaceAll("(\\d{4})(?=\\d)(?=\\d)(?=\\d)", "$1 ");
//Remove the listener
etCreditCardNumber.removeTextChangedListener(this);
int index = etCreditCardNumber.getSelectionEnd();
if (index == 5 || index == 10 || index == 15)
if (count > before)
index++;
else
index--;
//Assign processed text
etCreditCardNumber.setText(processed);
try {
etCreditCardNumber.setSelection(index);
} catch (Exception e) {
e.printStackTrace();
etCreditCardNumber.setSelection(s.length() - 1);
}
//Give back the listener
etCreditCardNumber.addTextChangedListener(this);
}
@Override
public void afterTextChanged(Editable s) {
}
});
ここに提示された答えは、削除、中間操作からの削除などでは適切に機能しないようです。これが私のコードです。入力の長さは制限されませんが、さまざまな挿入と削除で問題ないようです。
import Android.text.Editable;
import Android.text.TextWatcher;
import Android.view.KeyEvent;
import Android.view.View;
import Android.widget.EditText;
public class HyphenDelimitTextWatcher implements TextWatcher {
EditText mEditText;
boolean mInside = false;
boolean mWannaDeleteHyphen = false;
boolean mKeyListenerSet = false;
final static String MARKER = "|"; // filtered in layout not to be in the string
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if(!mKeyListenerSet) {
mEditText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
try {
mWannaDeleteHyphen = (keyCode == KeyEvent.KEYCODE_DEL
&& mEditText.getSelectionEnd() - mEditText.getSelectionStart() <= 1
&& mEditText.getSelectionStart() > 0
&& mEditText.getText().toString().charAt(mEditText.getSelectionEnd() - 1) == '-');
} catch (IndexOutOfBoundsException e) {
// never to happen because of checks
}
return false;
}
});
mKeyListenerSet = true;
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mInside) // to avoid recursive calls
return;
mInside = true;
int currentPos = mEditText.getSelectionStart();
String string = mEditText.getText().toString().toUpperCase();
String newString = makePrettyString(string);
mEditText.setText(newString);
try {
mEditText.setSelection(getCursorPos(string, newString, currentPos, mWannaDeleteHyphen));
} catch (IndexOutOfBoundsException e) {
mEditText.setSelection(mEditText.length()); // last resort never to happen
}
mWannaDeleteHyphen = false;
mInside = false;
}
@Override
public void afterTextChanged(Editable s) {
}
private String makePrettyString(String string) {
String number = string.replaceAll("-", "");
boolean isEndHyphen = string.endsWith("-") && (number.length()%4 == 0);
return number.replaceAll("(.{4}(?!$))", "$1-") + (isEndHyphen ?"-":"");
}
private int getCursorPos(String oldString, String newString, int oldPos, boolean isDeleteHyphen) {
int cursorPos = newString.length();
if(oldPos != oldString.length()) {
String stringWithMarker = oldString.substring(0, oldPos) + MARKER + oldString.substring(oldPos);
cursorPos = (makePrettyString(stringWithMarker)).indexOf(MARKER);
if(isDeleteHyphen)
cursorPos -= 1;
}
return cursorPos;
}
public HyphenDelimitTextWatcher(EditText editText) {
mEditText = editText;
}
}
使用法:
mSomeEditText.addTextChangedListener(new HyphenDelimitTextWatcher(mSomeEditText));
これはすべてのケースで機能します。文字を挿入または削除すると、フォーマットは常に正しくなります。設定してください
Android:inputType="number"
/
myEditText.addTextChangedListener(new TextWatcher() {
private final String space = "-"; // you can change this to whatever you want
private final Pattern pattern = Pattern.compile("^(\\d{4}"+space+"{1}){0,3}\\d{1,4}$"); // check whether we need to modify or not
@Override
public void onTextChanged(CharSequence s, int st, int be, int count) {
String currentText = myEditText.getText().toString();
if (currentText.isEmpty() || pattern.matcher(currentText).matches())
return; // no need to modify
String numbersOnly = currentText.trim().replaceAll("[^\\d.]", "");; // remove everything but numbers
String formatted = "";
for(int i = 0; i < numbersOnly.length(); i += 4)
if (i + 4 < numbersOnly.length())
formatted += numbersOnly.substring(i,i+4)+space;
else
formatted += numbersOnly.substring(i);
myEditText.setText(formatted);
myEditText.setSelection(myEditText.getText().toString().length());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable e) {}
});