更改drawable时,Android按钮保持按下状态
我想创建一个按钮,它第一次按下时变红,第二次按下时变回正常的灰色(并执行一些操作,如删除文件)。这是一种确认用户确实想要启动删除操作的方法 为此,我将背景可绘制更改为LayerDrawable,在默认可绘制的基础上增加了一个ColorDrawable。然后根据状态将ColorDrawable的alpha设置为0或255 第一次单击时切换为红色可以工作,但第二次单击时,按钮会变为黄色,如同处于按下状态一样,同时应恢复为正常的灰色 演示代码:更改drawable时,Android按钮保持按下状态,android,user-interface,android-drawable,Android,User Interface,Android Drawable,我想创建一个按钮,它第一次按下时变红,第二次按下时变回正常的灰色(并执行一些操作,如删除文件)。这是一种确认用户确实想要启动删除操作的方法 为此,我将背景可绘制更改为LayerDrawable,在默认可绘制的基础上增加了一个ColorDrawable。然后根据状态将ColorDrawable的alpha设置为0或255 第一次单击时切换为红色可以工作,但第二次单击时,按钮会变为黄色,如同处于按下状态一样,同时应恢复为正常的灰色 演示代码: package com.example.test; i
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();
}
});
}
}
我认为你想要实现的目标可以很容易地通过使用切换按钮来实现,而不是使用普通按钮并将其作为背景 切换按钮可以处理您的第一次点击和第二次点击的问题,因为他们是为了切换 我想说的是使用切换开关而不是普通按钮,然后根据您的情况,您可以做两件事: 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="" />
为什么不使用选择器,并将选择器放在可绘图文件夹中。 假设您的button_state.xml位于drawable文件夹中
<?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" />
现在我自己找到了答案:每个Drawable引用一个回调对象,如果需要重画,它会被通知。如果将可绘制对象指定给视图,则此视图为回调;如果它是复合可绘制对象(如LayerDrawable)的一部分,则此复合对象为回调 代码行
button.setBackgroundDrawable(new LayerDrawable(new Drawable[] {
button.getBackground(), cd}));
现在确实首先将按钮的默认可绘制内容放入LayerDrawable(因此默认背景的回调设置为LayerDrawable)。然后将按钮的默认背景替换为新创建的Drawable。发生这种情况时,上一个Drawable的回调被设置为null
最终,默认后台没有回调来通知状态更改后的必要重画,并且(视觉上)保持在错误的状态
正确的方法是:
Drawable oldBg = button.getBackground();
button.setBackgroundDrawable(null);
button.setBackgroundDrawable(new LayerDrawable(
new Drawable[] {oldBg, cd}));
首先“断开”默认背景,然后创建并设置新背景。如果我理解正确,这将仅在按下或聚焦状态下使用自定义绘图。但实际上我需要一个新的状态(“action_requested”或其他),我不想让它看起来像一个切换按钮(因为它不会打开或关闭某些东西),所以我需要通过使用普通按钮的可拖动资源,使它看起来像一个普通按钮。由于这些资源在不同的Android版本(以及不同的设备制造商)之间可能会有所不同,甚至它们的名称似乎也没有标准化,这将是一个复杂的问题(也许我忽略了一些东西)为按钮背景创建9个补丁图片我的想法是,按钮应该看起来完全像一个普通的按钮,至少只要它不是红色的。你的建议(如果我理解正确的话)将意味着复制或引用Android系统的可绘制资源,这些资源可能会随着时间的推移或制造商之间的不同而改变内容甚至名称,这样特殊的按钮看起来就不再常规了