Changing tint color of Android EditText programmatically

后端 未结 5 661
孤城傲影
孤城傲影 2021-02-03 22:07

I am trying to change the tinting color of an EditText View programmatically during runtime. Basically i want to change what you would usually apply as ?attr/

相关标签:
5条回答
  • 2021-02-03 22:38

    I wrote a small component to achieve this behavior.

    Few important notes:

    • Old school setColorFilter method is used
    • To make tint work, first switch focus to other view, then tint EditText background drawable

    Usage

    ErrorLabelLayout layoutPassError = (ErrorLabelLayout) findViewById(R.id.layoutPasswordError)
    layoutPassError.setError("Password_is_wrong");
    // when you want to clear error e.g. in on text changed method
    layoutPassError.clearError();
    

    XML

    <com.view.material.ErrorLabelLayout
        android:id="@+id/layoutPasswordError"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="false">
    
        <EditText
            android:id="@+id/editPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:hint="Enter your password"/>
    </com.view.material.ErrorLabelLayout>
    

    Source

    public class ErrorLabelLayout extends LinearLayout implements ViewGroup.OnHierarchyChangeListener {
    
        private static final int ERROR_LABEL_TEXT_SIZE = 12;
        private static final int ERROR_LABEL_PADDING = 4;
    
        private TextView mErrorLabel;
        private Drawable mDrawable;
        private int mErrorColor;
    
        public ErrorLabelLayout(Context context) {
            super(context);
            initView();
        }
    
        public ErrorLabelLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView();
        }
    
        public ErrorLabelLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView();
        }
    
        private void initView() {
            setOnHierarchyChangeListener(this);
            setOrientation(VERTICAL);
            mErrorColor = Color.parseColor("#D32F2F");
            initErrorLabel();
        }
    
        private void initErrorLabel() {
            mErrorLabel = new TextView(getContext());
            mErrorLabel.setFocusable(true);
            mErrorLabel.setFocusableInTouchMode(true);
            mErrorLabel.setTextSize(ERROR_LABEL_TEXT_SIZE);
            mErrorLabel.setTextColor(mErrorColor);
            mErrorLabel.setPadding(dipsToPix(ERROR_LABEL_PADDING), 0, dipsToPix(ERROR_LABEL_PADDING), 0);
        }
    
        public void setErrorColor(int color) {
            mErrorColor = color;
            mErrorLabel.setTextColor(mErrorColor);
        }
    
        public void clearError() {
            mErrorLabel.setVisibility(INVISIBLE);
            mDrawable.clearColorFilter();
        }
    
        public void setError(String text) {
            mErrorLabel.setVisibility(VISIBLE);
            mErrorLabel.setText(text);
            // changing focus from EditText to error label, necessary for Android L only
            // EditText background Drawable is not tinted, until EditText remains focus
            mErrorLabel.requestFocus();
            // tint drawable
            mDrawable.setColorFilter(mErrorColor, PorterDuff.Mode.SRC_ATOP);
        }
    
        @Override
        public void onChildViewAdded(View parent, View child) {
            int childCount = getChildCount();
            if (childCount == 1) {
                mDrawable = getChildAt(0).getBackground();
                addView(mErrorLabel);
            }
        }
    
        @Override
        public void onChildViewRemoved(View parent, View child) {
        }
    
        private int dipsToPix(float dps) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dps, getResources().getDisplayMetrics());
        }
    }
    

    Tested on API 16 / 21 with com.android.support:appcompat-v7:22.1.1 library.

    0 讨论(0)
  • 2021-02-03 22:50

    setColorFilter not working for me. I used:

    Drawable wrappedDrawable = DrawableCompat.wrap(mView.getBackground());
    DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.red));
    mView.setBackgroundDrawable(wrappedDrawable);
    

    or

    DrawableCompat.setTint(mView.getBackground(), ContextCompat.getColor(this, R.color.red));
    

    Let's try.

    0 讨论(0)
  • 2021-02-03 22:55

    This works for me:

    editText.getBackground().setColorFilter(getResources().getColor(R.color.your_color),
                                            PorterDuff.Mode.SRC_ATOP);
    

    Source: Changing EditText bottom line color with appcompat v7

    0 讨论(0)
  • 2021-02-03 22:55

    Try to create a custom EditText and add this.setBackgroundTintList( ColorStateList.valueOf( color ) ); into constructor.

    0 讨论(0)
  • 2021-02-03 22:57

    With the newly introduced android.support.v4.graphics.drawable.DrawableCompat#setTint setting the color is now possible.

    0 讨论(0)
提交回复
热议问题