如何设置不同状态的图片按钮背景图像?

81

我想要有两种状态的图像按钮:i) 正常 ii) 触摸(或点击)。

我已经将正常图像设置为imagebutton背景,我正在尝试从onclick方法中更改图像(按下),但是它没有变化。

如果我按下图像按钮,则希望图像从正常变为按下状态,直到我按下其他按钮,但这并没有发生。

有人能否建议我如何使用选择器或在运行时实现这一点?

这是我的imagebuttonpanel代码。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal"
  android:gravity="bottom"
  android:id="@+id/buttonpanel">
  <ImageButton android:id="@+id/buttonhome"
               android:layout_width="80dp"
               android:layout_height="36dp"
               android:focusable="true" 
               android:background="@drawable/homeselector">
               </ImageButton>
  <ImageButton android:id="@+id/buttonsearch"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/searchselector"
               android:focusable="true">
               </ImageButton>>
  <ImageButton android:id="@+id/buttonreg"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/registerselector"
               android:focusable="true">
               </ImageButton>>
  <ImageButton android:id="@+id/buttonlogin"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/loginselector"
               android:focusable="true">
               </ImageButton>
</LinearLayout>

我的选择器 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/homehover" 
        /> <item android:state_focused="true" android:drawable="@drawable/homehover" 
        /> <item android:drawable="@drawable/home" /> <item android:state_window_focused="true" 
        android:drawable="@drawable/homehover" /> -->
    <item android:state_enabled="false" android:drawable="@drawable/homehover" />
    <item android:state_pressed="true" android:state_enabled="true"
        android:drawable="@drawable/homehover" />
    <item android:state_focused="true" android:state_enabled="true"
        android:drawable="@drawable/homehover" />
    <item android:state_enabled="true" android:drawable="@drawable/home" />

</selector> 

我也尝试了在ontouch和onclick事件中更改图像资源,但是这并没有帮助。


我想你正在寻找类似于这个的东西。之前我也曾提过类似的问题。 - Federico klez Culloca
9个回答

225
在你的drawable文件夹下创建一个像这样的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="false"
        android:drawable="@drawable/btn_sendemail_disable" />
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/btn_send_email_click" />
    <item
        android:state_focused="true"
        android:state_enabled="true"
        android:drawable="@drawable/btn_sendemail_roll" />
    <item
        android:state_enabled="true"
        android:drawable="@drawable/btn_sendemail" />
</selector>

根据需要设置图像,然后将此xml设置为您的imageButton的背景。


11
可以的,这将被称为选择器 XML。 - Aman Alam
4
@Hitendra:我猜OP已经知道这一点了。问题可以解释为为什么选择器没有被调用。 - Samuel
状态启用是必要的吗? - Dr.jacky
4
这适用于普通的Button,但不适用于ImageButton。同样,这将适用于ImageButtonandroid:src属性,但不适用于android:background属性。除了格式和可绘制对象的名称之外,您的选择器与原始发布者的有什么区别?我有什么遗漏吗? - Alexander Malakhov
您不需要使用语句 android:state_enabled="true",它与 if( x == 1 ){}else if( x != 1 && ... ){} 相同。第一次检查后,android:state_enabled 肯定是 true - γηράσκω δ' αεί πολλά διδασκόμε
显示剩余2条评论

14
尝试这个。
btn.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        btn.setBackgroundResource(R.drawable.icon);
    }
});

有没有人有想法,我可以做到它? - Hitendra

9

我有另一种解决方案可以帮助我,因为我只有两个不同的状态:

  • 要么该项未被点击
  • 要么它被点击并突出显示

在我的.xml文件中,我像这样定义了ImageButton:

 <ImageButton
    android:id="@+id/imageButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/selector" />

对应的选择器文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/ico_100_checked" android:state_selected="true"/>
    <item android:drawable="@drawable/ico_100_unchecked"/>

</selector>

在我的onCreate方法中,我调用了:
final ImageButton ib = (ImageButton) value.findViewById(R.id.imageButton);

    OnClickListener ocl =new OnClickListener() {
        @Override
        public void onClick(View button) {
            if (button.isSelected()){
                button.setSelected(false);
            } else {
                ib.setSelected(false);
                //put all the other buttons you might want to disable here...
                button.setSelected(true);
            }
        }
    };

ib.setOnClickListener(ocl);
//add ocl to all the other buttons

完成了。希望这可以帮助你。花费了我一些时间才弄清楚。


8

你好,请尝试以下代码,它对你会有帮助:

((ImageView)findViewById(R.id.ImageViewButton)).setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN)
            ((ImageView) v.findViewById(R.id.ImageViewButton)).setImageResource(R.drawable.image_over);

        if(event.getAction() == MotionEvent.ACTION_UP)
            ((ImageView) v.findViewById(R.id.ImageViewButton)).setImageResource(R.drawable.image_normal);

        return false;
    }
});

1
实际上,这也不是很有效,如果 action_up 发生在不同的视图上。尝试使用 event.getAction() == MotionEvent.ACTION_CANCEL 而不是 ACTION_UP。 - chug2k

3
我认为你的问题不在于选择器文件。 你需要添加:
<imagebutton ..
    android:clickable="true"
/>

针对图像按钮:

默认情况下onClick在listitem级别(父级)被处理,而图像按钮不会接收到onClick事件。

当您添加上述属性时,图像按钮将接收该事件并使用选择器。

请参考此POST,其中解释了复选框的相同内容。


1
如果您想要一个按下的图像按钮,那么图像应该从正常状态变为按下状态。
但是最好的方法是自定义RadioButton并将它们用于组。我看过一个例子。抱歉,我不记得那个链接了。
但是如果您想避免这种情况。您需要将以下内容添加到您的selector.xml中。
完成后,只需转到您的代码并添加此内容。
public void onClick ( View v ) {
    myImageButton.setSelected ( true ) ;
 }

你会看到结果。但你必须管理哪个按钮最近被按下的状态。这样你就可以设置

  myOLDImageButton.setSelected ( false ) ;

我建议你将所有按钮引用放在一个数组中。

1

不,我认为这不是他想要的。分段控件是完全不同的UI元素。他想要一个可以改变状态的按钮。 - Henley

0

你尝试过CompoundButton吗? CompoundButton具有可选属性,完全符合您的需求。请使用这些替换ImageButtons。

  <CompoundButton android:id="@+id/buttonhome"
                  android:layout_width="80dp"
                  android:layout_height="36dp"
                  android:background="@drawable/homeselector"/>

将选择器xml更改为以下内容。可能需要进行一些修改,但一定要使用state_checked代替state_pressed

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/homehover" />
    <item android:state_checked="true" android:state_enabled="true"
          android:drawable="@drawable/homehover" />
    <item android:state_focused="true" android:state_enabled="true"
          android:drawable="@drawable/homehover" />
    <item android:state_enabled="true" android:drawable="@drawable/home" />

</selector> 

CompoundButton.OnCheckedChangeListener中,您需要根据条件选中或取消其他内容。
 mButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

   public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            // Uncheck others. 
        }
   }
});

同样地,为每个按钮设置一个OnCheckedChangeListener,当它被选中时,将取消选中其他按钮。希望这能帮到你。

你不能直接在XML中使用CompoundButton,因为它是一个抽象类。 - Dan Hulme

0
你可以在res/drawable文件夹中创建选择器文件。

example: res/drawable/selector_button.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/btn_enabled" />
</selector>

在布局活动、片段或其他方面

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/selector_bg_rectangle_black"/>

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