Search code examples
androidandroid-edittextandroid-design-libraryandroid-textinputlayout

Unable to use drawable in EditText inside TextInputLayout


I recently upgraded Android Design library from 24.2.1 to 25.0.0. After this the "drawableX" feature in EditText doesn't work.

EDIT 01.11: I learned that setting drawable in xml works if you use android:drawableStart instead of android:drawableLeft. But setting setting drawables programatically does not work. I use this to make a "Clear"-button to empty the EditText. But this feature is broken now. I would appreciate any work-arounds or knowledge about if this is intentional from Google or a bug!

My code for Clearable edit-text that worked before but doesn't now:

public class ClearableErrorTextInputEditText extends ErrorTextInputEditText implements View.OnFocusChangeListener, View.OnTouchListener, TextWatcher {

private Drawable resIcon;
private OnFocusChangeListener childFocusListener;

public ClearableErrorTextInputEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setup();
}

public ClearableErrorTextInputEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    setup();
}

public ClearableErrorTextInputEditText(Context context) {
    super(context);
    setup();
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
        if (getCompoundDrawables()[2] != null) {
            final boolean tappedClose = event.getX() > (getWidth() - getPaddingRight() - resIcon.getIntrinsicWidth());
            if (tappedClose) {
                setText("");
                return false; // true will fail on emulator running 2.1 and physical keyboard / scroll wheel
            }
        }
    }
    return false;
}

@Override
public void setOnFocusChangeListener(OnFocusChangeListener l) {
    childFocusListener = l;
}

@Override
public void onFocusChange(View v, boolean hasFocus) {
    setClearIconVisible(hasFocus && getText().length() > 0);

    if (childFocusListener!=null){
        childFocusListener.onFocusChange(v, hasFocus);
    }
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
    super.onTextChanged(s, start, before, count);
    setClearIconVisible(isFocused() && s.length() > 0);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // not interesting

@Override
public void afterTextChanged(Editable s) {} //  // not interesting

private void setup() {
    if(isInEditMode()){
        return;
    }

    resIcon = getResources().getDrawable(R.drawable.ic_clear, null);
    resIcon.setBounds(0, 0, resIcon.getIntrinsicWidth(), resIcon.getIntrinsicHeight());

    setClearIconVisible(false);

    super.setOnTouchListener(this);
    super.setOnFocusChangeListener(this);
    addTextChangedListener(this);
}

private void setClearIconVisible(final boolean visible){
    final Drawable icon = visible ? resIcon : null;
    setCompoundDrawables(getCompoundDrawables()[0],
            getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
}

Solution

  • Based on the answer by Ahmed Ashraf G, I was able to find the solution. Changing the following code:

    setCompoundDrawables(getCompoundDrawables()[0],
            getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
    

    to:

    setCompoundDrawablesRelative(getCompoundDrawablesRelative()[0],
                getCompoundDrawablesRelative()[1], icon, getCompoundDrawablesRelative()[3]);
    

    From other places on StackOverflow (the documentation does NOT mention this) the difference between xxxCompoundDrawablesXxx and xxxCompundDrawablesRelativeXxx is that the relative versions take into account RTL-languages, ie they are the same as using drawableStart instead of drawableLeft.

    So in conclusion, Google has broken all methods that are not RTL-methods for EditText inside TextInputLayout. Since the new methods are added in API level 17 I see this as major bug, that will probably be fixed in future updates