J'ai testé la solution de @ Jeff sur la version 4.2, 4.4, 6.0. Sur les versions 4.2 et 6.0, cela fonctionne bien. Mais sur 4.4, cela ne fonctionne pas.
J'ai trouvé un moyen simple de contourner ce problème. Le point clé est d'insérer un caractère invisible dans le contenu de EditText au début et de ne pas laisser l'utilisateur déplacer le curseur avant ce caractère. Ma façon est d'insérer un caractère d'espace blanc avec un ImageSpan de largeur nulle dessus. Voici mon code.
@Override
public void afterTextChanged(Editable s) {
String ss = s.toString();
if (!ss.startsWith(" ")) {
int selection = holder.editText.getSelectionEnd();
s.insert(0, " ");
ss = s.toString();
holder.editText.setSelection(selection + 1);
}
if (ss.startsWith(" ")) {
ImageSpan[] spans = s.getSpans(0, 1, ImageSpan.class);
if (spans == null || spans.length == 0) {
s.setSpan(new ImageSpan(getResources().getDrawable(R.drawable.zero_wdith_drawable)), 0 , 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
Et nous avons besoin d'un EditText personnalisé qui a un SelectionChangeListener
public class EditTextSelectable extends android.support.v7.widget.AppCompatEditText {
public interface OnSelectChangeListener {
void onSelectChange(int start, int end);
}
private OnSelectChangeListener mListener;
public void setListener(OnSelectChangeListener listener) {
mListener = listener;
}
...constructors...
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
if (mListener != null) {
mListener.onSelectChange(selStart, selEnd);
}
super.onSelectionChanged(selStart, selEnd);
}
}
Et la dernière étape
holder.editText.setListener(new EditTextSelectable.OnSelectChangeListener() {
@Override
public void onSelectChange(int start, int end) {
if (start == 0 && holder.editText.getText().length() != 0) {
holder.editText.setSelection(1, Math.max(1, end));
}
}
});
Et maintenant, nous avons terminé ~ Nous pouvons détecter l'événement de touche de retour arrière lorsque EditText n'a pas de contenu réel, et l'utilisateur ne saura rien de notre astuce.