He probado la solución de @ Jeff en la versión 4.2, 4.4, 6.0. En 4.2 y 6.0, funciona bien. Pero en 4.4, no funciona.
Encontré una manera fácil de solucionar este problema. El punto clave es insertar un carácter invisible en el contenido de EditText al principio, y no permitir que el usuario mueva el cursor antes de este carácter. Mi forma es insertar un carácter de espacio en blanco con un ImageSpan de ancho cero en él. Aquí está mi código.
@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);
}
}
}
Y necesitamos un EditText personalizado que tenga 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);
}
}
Y el ultimo paso
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));
}
}
});
Y ahora, hemos terminado ~ Podemos detectar el evento de tecla de retroceso cuando EditText no tiene contenido real, y el usuario no sabrá nada sobre nuestro truco.