基于状态的 ImageButton 图标着色

7

我目前正在尝试在一些ImageButtons上实现着色,这些ImageButtons当前具有纯白色的Drawable。着色颜色应该由StateList提供,并且应根据按钮当前状态而改变。StateList看起来像:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#FF0000"/>
    <item android:color="#00FF00" android:state_enabled="false"/>
    <item android:color="#0000FF" android:state_pressed="true" android:state_enabled="true"/>
</selector>

而按钮的布局XML片段如下:

<ImageButton
    android:id="@+id/btnNext"
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/vertical_content_padding"
    android:layout_marginEnd="@dimen/horizontal_content_padding"
    android:contentDescription="@string/next"
    android:src="@drawable/ic_chevron_right_white_24dp"
    android:tint="@color/state_btn_tint_light"/>

默认的颜色状态列表中的着色被选择并正确显示。但是禁用按钮或按下它并不会触发图标的任何颜色更改。我也尝试使用setImageTintList来以编程方式设置它。
2个回答

2

你的代码应该可以工作。然而,有一个错误:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#FF0000"/>
    <item android:color="#00FF00" android:state_enabled="false"/>
    <item android:color="#0000FF" android:state_pressed="true" android:state_enabled="true"/>
</selector>

您需要反转状态的顺序。

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#0000FF" android:state_pressed="true" android:state_enabled="true"/>
    <item android:color="#00FF00" android:state_enabled="false"/>
    <item android:color="#FF0000"/>
</selector>

我不完全确定它在内部是如何工作的,但它似乎像If/Else语句一样运作。如果第一个条件失败,则会转到第二个条件。由于您的第一个项目没有任何条件,因此它将始终被选中,其他项目将被忽略,给人的印象是颜色状态列表根本不起作用。因此,请始终将具有最严格条件的颜色状态放在第一位。


1
我会尽力帮助您翻译。以下是需要翻译的内容:

我将简化我的回答,希望有所帮助。 您可以随时在colors.xml中输入任何颜色,对吧?那么让我们使用它。

您可以像这样创建一个所需颜色的整数数组列表

integer[] colors = new integer[]{R.color.white, R.color.black, ...};

现在,像这样的imageButton可以采用背景色调,例如:
imagebutton.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(mContext,R.color.white)));

现在让我们将它们与动画结合起来,创建动画方法:

public ValueAnimator ColorAnimation(ImageButton imagebutton, int colorFrom, int colorTo){
        ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
        anim .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                imagebutton.setImageTintList(ColorStateList.valueOf((int) animation.getAnimatedValue()));
            }
        });
        anim.setInterpolator(new DecelerateInterpolator());
        anim.setDuration(300); // -- Whatever time
        return anim;
    };

现在,在您的活动中,您可以像这样实现它:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout);
        mContext = this;
        ...

        ImageButton myButton = (ImageButton) findViewById(R.id.imagebutton);

        //-- Define All the Colors You want
        integer[] listOfColors = new integer[]{R.color.white, R.color.black, R.color.yellow, R.color.red, R.color.blue};

        //-- With this you can randomly get a color from the list
        int aColor = (int)(Math.random()*listOfColors.length); 

        //-- Your Default imageButton Color
        int DefaultColor = ContextCompat.getColor(mContext,R.color.white);

        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ColorAnimation(myButton, DefaultColor, listOfColors[aColor]).start;
                //-- You can even enter whatever color want directly for "colorTo"
                //-- You can Reverse this animation as well
            }
        });

        ...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接