0

我想创建一个按钮,该按钮在第一次按下时变为红色,第二次变为正常灰色(并执行一些操作,例如删除文件)。这是一种确认用户确实想要开始删除操作的方法。

为此,我将背景可绘制对象更改为 LayerDrawable,并在默认可绘制对象之上添加了一个额外的 ColorDrawable。然后根据状态将 ColorDrawable 的 alpha 设置为 0 或 255。

在第一次单击时切换为红色有效,但在第二次单击时,按钮变为黄色,因为它处于按下状态,而它应该回到正常的灰色。

演示代码:

package com.example.test;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class TestActivity extends Activity {

    Button button;
    boolean showRed;
    ColorDrawable cd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        button = new Button(this);
        button.setText("Delete");

        // Following two lines don't matter, focus isn't the problem
        button.setFocusable(false);
        button.setFocusableInTouchMode(false);

        cd = new ColorDrawable(0xffff0000);
        cd.setAlpha(0);

        button.setBackgroundDrawable(new LayerDrawable(new Drawable[] {
                button.getBackground(), cd}));

        setContentView(button);


        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showRed = !showRed;

                if (showRed)
                    cd.setAlpha(255);
                else
                    cd.setAlpha(0);

                // Following line doesn't matter
                button.setSelected(false);

                button.getBackground().invalidateSelf();
            }
        });
    }
}
4

3 回答 3

0

现在我自己找到了答案:每个 Drawable 都引用了一个 Callback 对象,如果需要重绘,该对象就会被告知。如果drawable被分配给一个View,这个View就是Callback,如果它是一个复合drawable(比如LayerDrawable)的一部分,这个复合就是Callback。

代码行

    button.setBackgroundDrawable(new LayerDrawable(new Drawable[] {
            button.getBackground(), cd}));

现在确实首先将按钮的默认drawable放入LayerDrawable(因此默认背景的Callback设置为LayerDrawable)。然后用新创建的 Drawable 替换按钮的默认背景。发生这种情况时,前一个 Drawable 的 Callback 设置为 null。

最后,默认背景没有回调来通知状态更改后必要的重绘,并且(视觉上)保持在错误的状态。

执行上述操作的正确方法是:

    Drawable oldBg = button.getBackground();
    button.setBackgroundDrawable(null);
    button.setBackgroundDrawable(new LayerDrawable(
            new Drawable[] {oldBg, cd}));

首先“断开”默认背景,然后创建并设置新背景。

于 2013-05-31T13:31:20.380 回答
0

我认为您想要实现的目标可以通过使用切换按钮而不是普通按钮并为其提供背景来轻松完成。

Toggle Button 可以处理您的第一次点击和第二次点击问题,因为它们是为了切换。

我要说的是使用拨动开关而不是普通按钮,然后根据您的情况,您可以做两件事:

1.> 将切换按钮背景分配给一个选择器 xml 文件,该文件将处理不同状态的颜色(按下、聚焦、默认等)。对于各州,请查看开发者网站上的文档。

2.>你可以给背景一个默认颜色然后你可以做的是改变切换选中和未选中功能的颜色。

我建议切换按钮的唯一原因是它很容易处理第一次单击和第二次单击选项。

此外,一旦您将切换按钮背景从默认更改为任何颜色或可绘制,它就不再看起来像一个开关。您还可以通过将 textOn 和 textOff 属性保留为空白来删除写入的 on 和 off

<ToggleButton
    android:id="@+id/toggleButton1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/textView1"
    android:layout_below="@+id/textView1"
    android:layout_marginTop="42dp"
    android:text="ToggleButton"
    android:background="@android:color/white"
    android:textOn=""
    android:textOff="" />
于 2013-05-30T10:39:52.037 回答
0

您为什么不为此目的使用选择器并将选择器放在可绘制文件夹中。这是假设您在可绘制文件夹中的 button_state.xml。

<?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
     android:drawable="@drawable/button_pressed" /> <!-- pressed -->
     <item android:state_focused="true"
     android:drawable="@drawable/button_focused" /> <!-- focused -->
     <item android:drawable="@drawable/button_normal" /> <!-- default -->
 </selector>

然后在您的按钮中,您可以添加以下内容:

<Button
        android:id="@+id/homeButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10px"
        android:background="@drawable/button_state" />
于 2013-05-30T10:41:16.080 回答