按住退格键不会一一清除文本
Hold on backspace doesn't clear text one by one
我有一个 EditText 实现 TextWatcher,但退格键有问题。
按住退格时前5个字符会被一一清除,但转换为图像的后5个字符无法在按住退格时一一清除。
看图:
MainActivity.java
public class MainActivity extends AppCompatActivity {
Spannable.Factory spannableFactory;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spannableFactory = Spannable.Factory
.getInstance();
final EditText 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) {
editText.removeTextChangedListener(this);
if (s.length() >= 5) {
editText.setText(getTextToIcon(getApplicationContext(), s));
}
if(count!=0){ // != key delete
if (s.length() - 1 > start) {
editText.setSelection(start + 1);
} else {
editText.setSelection(s.length());
}
}else{ // = key delete
editText.setSelection(start);
}
editText.addTextChangedListener(this);
}
@Override
public void afterTextChanged(Editable s) {}
});
}
public Spannable getTextToIcon(Context context, CharSequence text) {
StringBuilder stringBuilder = new StringBuilder(text);
Spannable spannable = spannableFactory.newSpannable(stringBuilder);
int index = text.length() - 1;
for(int i = 5; i<=index; i++){
spannable.setSpan(new ImageSpan(context, android.R.drawable.star_on),
i, i + 1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannable;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="10"
android:inputType="number" />
</LinearLayout>
兄弟,有bug的代码如下:
if (s.length() >= 5) {
editText.setText(getTextToIcon(getApplicationContext(), s));
}
你应该改成这样:
if (count != 0 && s.length() >= 5) {
// just set the text to the icon in input state instead of pressing delete key in soft method
editText.setText(getTextToIcon(getApplicationContext(), s));
}
希望对您有所帮助。
现在我从这个link中找到了解决方案
希望对其他人有帮助。
editText.addTextChangedListener( new TextWatcher() {
boolean isEdiging;
@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(isEdiging) return;
isEdiging = true;
String str = s.toString().replaceAll("[^\d]", "");
double s1 = 0;
try {
s1 = Double.parseDouble(str);
}catch (NumberFormatException e){
e.printStackTrace();
}
NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
((DecimalFormat)nf2).applyPattern("###,###.###");
s.replace(0, s.length(), nf2.format(s1));
isEdiging = false;
}
});
}
我有一个 EditText 实现 TextWatcher,但退格键有问题。 按住退格时前5个字符会被一一清除,但转换为图像的后5个字符无法在按住退格时一一清除。
看图:
MainActivity.java
public class MainActivity extends AppCompatActivity { Spannable.Factory spannableFactory; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spannableFactory = Spannable.Factory .getInstance(); final EditText 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) { editText.removeTextChangedListener(this); if (s.length() >= 5) { editText.setText(getTextToIcon(getApplicationContext(), s)); } if(count!=0){ // != key delete if (s.length() - 1 > start) { editText.setSelection(start + 1); } else { editText.setSelection(s.length()); } }else{ // = key delete editText.setSelection(start); } editText.addTextChangedListener(this); } @Override public void afterTextChanged(Editable s) {} }); } public Spannable getTextToIcon(Context context, CharSequence text) { StringBuilder stringBuilder = new StringBuilder(text); Spannable spannable = spannableFactory.newSpannable(stringBuilder); int index = text.length() - 1; for(int i = 5; i<=index; i++){ spannable.setSpan(new ImageSpan(context, android.R.drawable.star_on), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return spannable; } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLength="10" android:inputType="number" /> </LinearLayout>
兄弟,有bug的代码如下:
if (s.length() >= 5) {
editText.setText(getTextToIcon(getApplicationContext(), s));
}
你应该改成这样:
if (count != 0 && s.length() >= 5) {
// just set the text to the icon in input state instead of pressing delete key in soft method
editText.setText(getTextToIcon(getApplicationContext(), s));
}
希望对您有所帮助。
现在我从这个link中找到了解决方案 希望对其他人有帮助。
editText.addTextChangedListener( new TextWatcher() {
boolean isEdiging;
@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(isEdiging) return;
isEdiging = true;
String str = s.toString().replaceAll("[^\d]", "");
double s1 = 0;
try {
s1 = Double.parseDouble(str);
}catch (NumberFormatException e){
e.printStackTrace();
}
NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
((DecimalFormat)nf2).applyPattern("###,###.###");
s.replace(0, s.length(), nf2.format(s1));
isEdiging = false;
}
});
}