首页 文章

以编程方式更改Android EditText的色调颜色

提问于
浏览
20

我试图在运行时以编程方式更改 EditText View的着色颜色 . 基本上我想改变你通常应用的 ?attr/colorControlNormal ,如default background drawable .

仅使用一种颜色设置 new ColorsStateList ,无法正确应用更改背景色调:

editText.setBackgroundTintList( ColorStateList.valueOf( color ) );

首先,结果应用于所有 EditText ,尽管应用了色调列表并在内部改变了drawable . 此外,默认背景1中指定的alpha在开头可见 .

这是在第一个 EditText 上设置色调颜色的结果:

outcome of setting the tint color on just the first EditText

所以我的问题是:如何以编程方式将色调正确应用于 EditText

4 回答

  • 7

    使用新引入的 android.support.v4.graphics.drawable.DrawableCompat#setTint 设置,现在可以使用颜色 .

  • 32

    尝试创建自定义 EditText 并将 this.setBackgroundTintList( ColorStateList.valueOf( color ) ); 添加到构造函数中 .

  • 0

    这对我有用:

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

    资料来源:Changing EditText bottom line color with appcompat v7

  • 11

    我写了一个小组件来实现这种行为 .

    几个重要的注意事项:

    • 使用旧学校 setColorFilter 方法

    • 要使色调工作,首先将焦点切换到其他视图,然后着色 EditText background drawable

    用法

    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>
    

    资源

    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());
        }
    }
    

    在带有 com.android.support:appcompat-v7:22.1.1 库的API 16/21上进行了测试 .

相关问题