像按下一样更改按钮背景颜色,但无需用户按下它

Change button background color as if pressed, but without the user pressing it

在 Android 上,按下 Button 会更改其背景颜色。

我们如何告诉按钮它被按下(不触发 onClick 动作),以便它改变颜色,没有用户按下它?(例如由滑动动作触发)

它应该短暂地改变颜色,然后再变回来。

关于保持按下状态有quite a few questions。本题问,如何简单设置button_pressed状态,好像点击了,但没有真正的点击。

Button.setPressed(true) 没有变色,Button.performClick().

也没有变色

此时要改变按钮的颜色,可以使用setOnTouchListener如:

button.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                //Button Pressed
            }
            if(event.getAction() == MotionEvent.ACTION_UP){
                 //finger was lifted
            }
            return false;
        }
    });

首先,在 XML 中创建按钮悬停、单击等时的效果。将此样式放入您的可绘制对象中。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Pressed button -->
    <item android:drawable="@color/dark_green"
        android:state_focused="true"
        android:state_pressed="false"
        />
    <item android:drawable="@color/dark_green"
        android:state_focused="true"
        android:state_pressed="true"
        />
    <item android:drawable="@color/dark_green"
        android:state_focused="false"
        android:state_pressed="true"/>

    <!-- Normal button -->
    <item android:drawable="@color/green"
        android:state_focused="false"
        android:state_pressed="false"/>
</selector>

然后在您的 XML 中使用以下方式启动样式:

<Button
 android:layout_width="wrap_content"
 android:layout_height="match_parent"
 android:background="@drawable/the_style_in_drawable"
 android:text="click"/>

通过将样式放入 XML,您不必在单击按钮时启动样式。 Android 将检测按钮状态并为您完成工作。只记得将状态放在选择器中。

用于按钮颜色更改幻觉的 AsyncTask:

private class ChangeButtonColorMomentarily extends AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(50, 50, 50)));//pressed state
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result) {
        btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(200, 200, 200)));//normal state
    }

}

另请注意,如果您的 API 16 以上使用 setBackground() 代替。

要更改按钮状态 无需 任何其他操作都可以通过

btn1.getBackground().setState(new int[]{android.R.attr.state_pressed});

要重置为普通,您使用

btn1.getBackground().setState(new int[]{android.R.attr.state_enabled});

一个Button的状态可以通过

找到
btn1.getBackground().getState();

返回 int[]。您可以将其值与 android.R.attr 进行比较以找出设置了哪些状态。

Example Code

private void simulateClick(final ImageButton button,
                           final long clickDuration) {
    button.getBackground().setState(new int[]{android.R.attr.state_pressed});
    new Thread(new Runnable() {
        public void run() {
            try {
                Thread.sleep(clickDuration);
            } catch ( InterruptedException e ) {
                // not bad if interrupted: sleeps a bit faster (can happen?)
            }
            Count.this.runOnUiThread(new Runnable() {
                    public void run() {
                        button.getBackground().setState(new int[]{android.R.attr.state_enabled});
                    }
                });
        }}).start();
}

说明

每个 View 都有一个 Drawable as background image. A Drawable can be of different subtypes, here it is a StateListDrawable, as defined per XML. (See 作为 XML 定义的可绘制对象的示例)。

这个 Drawable 可以被告知它处于哪个状态(通过 setState)并自己进行布局。