Search code examples
androidandroid-edittextandroid-canvasandroid-custom-viewright-to-left

RTL support to custom editext for drawable left


I have an edittext having an image as drawable left with a non-editable prefixed editext but now i wanted to make it to support rtl. Despite my effort I am not able to support rtl.

My Custom class is as follows,

public class PrefixedEditText extends TextInputEditText {

private String mPrefix = "+"; // can be hardcoded for demo purposes
private Rect mPrefixRect = new Rect(); // actual prefix size

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    getPaint().getTextBounds(mPrefix, 0, mPrefix.length(), mPrefixRect);
    mPrefixRect.right += getPaint().measureText(" "); // add some offset

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawText(mPrefix, super.getCompoundPaddingLeft(), getBaseline(), getPaint());
}

@Override
public int getCompoundPaddingLeft() {
    return super.getCompoundPaddingLeft() + mPrefixRect.width();
}

}

My xml call of this class is as follows,

<cl.dd.ui.PrefixedEditText
                    style="@style/edittext"
                    android:id="@+id/etCode"
                    android:maxLength="3"
                    android:drawableLeft="@drawable/icon_phone_number"
                    android:drawableStart="@drawable/icon_phone_number"
                    android:minWidth="@dimen/dim_img_width"
                    android:hint="@string/s_login_code"
                    android:tag="@string/s_login_country_code"
                    android:inputType="number"/>

Solution

  • To achieve the prefixed edit text with locale support just create a custom Edit Text and Draw the prefix as a drawable.

    Refer the code snippet below:

        /**
         * Custom EditText that displays a fixed prefix in line with the text.
         * The trick here is to draw the prefix as a drawable and attach it via
         * setCompoundDrawables().
         */
    
        public class PrefixEditText extends AppCompatEditText {
    
            private ColorStateList mPrefixTextColor;
    
            public PrefixEditText(Context context) {
                this(context, null);
            }
    
            public PrefixEditText(Context context, AttributeSet attrs) {
                this(context, attrs, android.R.attr.editTextStyle);
            }
    
            public PrefixEditText(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
                mPrefixTextColor = getTextColors();
            }
    
            public void setPrefix(String prefix) {
                if (Locale.getDefault().getLanguage().equalsIgnoreCase("en"))
                    setCompoundDrawables(new TextDrawable(prefix + " "), null, null, null);
                else if (Locale.getDefault().getLanguage().equalsIgnoreCase("ar"))
                    setCompoundDrawables(null, null, new TextDrawable(" " + prefix), null);
            }
    
            public void setPrefixTextColor(int color) {
                mPrefixTextColor = ColorStateList.valueOf(color);
            }
    
            private class TextDrawable extends Drawable {
                private String mText = "";
    
                TextDrawable(String text) {
                    mText = text;
                    setBounds(0, 0, (int) getPaint().measureText(mText) + 3, (int) getTextSize());
                }
    
                @Override
                public void draw(Canvas canvas) {
                    Paint paint = getPaint();
                    paint.setColor(mPrefixTextColor.getColorForState(getDrawableState(), 0));
                    int lineBaseline = getLineBounds(0, null);
                    canvas.drawText(mText, 0, canvas.getClipBounds().top + lineBaseline, paint);
                }
    
                @Override
                public void setAlpha(int alpha) {/* Not supported */}
    
                @Override
                public void setColorFilter(ColorFilter colorFilter) {/* Not supported */}
    
                @Override
                public int getOpacity() {
                    return 1;
    }
    }
    }