RTL support to custom editext for drawable left

2019-07-04 02:40发布

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"/>

4条回答
对你真心纯属浪费
2楼-- · 2019-07-04 03:07

You would need to make sure that supportsRtl is set to true in your AndroidManifest.xml

<application
    ...
    android:supportsRtl="true">

And set the layoutDirection to locale, inherit or rtl in your layout xml if you are targeting SDK 17+

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layoutDirection="locale">

If your target SDK is below 17, you would have to create another res directory like layout-ldrtl or values-ldrtl and maybe send an rtl flag to your custom view.

查看更多
放荡不羁爱自由
3楼-- · 2019-07-04 03:07

Here is what I can suggest.

Instead of extending TextInputEditText, create a custom view based on a layout.

The layout can be something like this:

<RelativeLayout
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">

     <TextView
         android:id="@+id/prefixTextView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentStart="true />

     <EditText
         android:id="@+id/editText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"     
         android:layout_toEndOf="@id/prefixTextView" />

</RelativeLayout>

Then, you can create a custom view, extending RelativeLayout with this layout. It will adapt to language direction changes.

There are a few drawbacks - the resulting View won't be in the EditText class hierarchy, and using it in a lot of places can end up hurting the UI performance, since it introduces nested layouts, but at least the RTL part will be OK.

查看更多
可以哭但决不认输i
4楼-- · 2019-07-04 03:10

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;
}
}
}
查看更多
啃猪蹄的小仙女
5楼-- · 2019-07-04 03:26

To achieve RTL just put drawableStart instead of drawableLeft. Like this :

<cl.dd.ui.PrefixedEditText
                    style="@style/edittext"
                    android:id="@+id/etCode"
                    android:maxLength="3"
                    android:drawableStart="@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"/>

This will do the trick.

查看更多
登录 后发表回答