开发者社区> 问答> 正文

selector 在 button上无效的问题:报错

我想在 selector 来改变按钮被按钮下的背景,可是根本就无效。

网上说将默认的背景item放在selector的最后,可是我放在了最后,依然无效,怎么回事?

这是我的selector文件:

<?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/btn_bg_1" />
    <!-- 按钮被聚焦时显示的背景 -->
    <item
        android:state_focused="true"
        android:drawable="@drawable/btn_bg_1" />
    <!-- 按钮默认显示的背景  -->
    <item 
        android:drawable="@drawable/btn_bg_0" />
</selector>
然后这是我在button上的相关属性设置:

<Button
	            android:id="@+id/searchBook_clear_btn"
	            android:layout_width="101dp"
	            android:layout_height="57dp"
	            android:layout_alignBaseline="@+id/searchBook_search_btn"
	            android:layout_alignBottom="@+id/searchBook_search_btn"
	            android:layout_alignParentRight="true"
	            android:layout_marginRight="20dp"
	            android:text="@string/searchBook_clear"
	            android:textSize="20sp"
	            android:textColor="#ffffff"
	            android:shadowColor="#000000"
		     android:shadowDx="1"
		     android:shadowDy="1"     
		     android:shadowRadius="1"
		     <!-- 控制button背景变化,btn_bg为selector控制文件 -->
	            android:background="@drawable/btn_bg" />
为什么会出现这样的情况,求解!!!



展开
收起
kun坤 2020-06-07 08:55:37 1067 0
1 条回答
写回答
取消 提交回答
  • 哇靠,原来按钮的事件监听竟然对控制按钮背景的 selector文件有影响。

    原来我的按钮事件监听是OnTouchListener方法,当我将按钮的事件监听修改为onClickListener方法后,竟然控制背景的 selector 文件就有效了。

    这是我的控制按钮背景的selector 文件:

    <?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/btn_bg_1" />
        
        <!-- 按钮默认显示的背景  -->
        <item 
            android:drawable="@drawable/btn_bg_0" />
    </selector>
    我的按钮事件监听:

    clearButton.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				// 将“关键词”输入框清空
    				keyWordEdt.setText("");
    			}
    		});
    我不知道我的这种情况和原因是不是个例。

    ######

    谷歌的官网里的例子都这样写的:

    XML file saved at res/drawable/button.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:state_hovered="true"
              android:drawable="@drawable/button_focused" /> <!-- hovered -->
        <item android:drawable="@drawable/button_normal" /> <!-- default -->
    </selector>
    This layout XML applies the state list drawable to a Button:

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

    ######我在按钮的监听事件上用了 onTouchListener。######

    首先要确认一点。官方的example中在drawable目录下面selector的文件名为button.xml,同时才能够在<Button>中用@drawable/button. 你的图片button_normal.png也应该放到drawable-hdpi,drawable-land-hdpi这些目录中,而不是放到drawable目录。android源码中的使用是这样的。你可以参考下。

    ###### @剑麟 能实现就好。官方源码里面这样做的。具体没看到哪里有文档说这个的区别。######回复 @thuai : 放在 drawable 文件夹下和放在 drawable-hdpi 文件夹下会有什么区别? 我将那个 selector 文件是放在 drawable-hdpi 文件夹中,然后用onClickListener,然后也可以实现该效果。###### @剑麟 selector文件放到drawable-hdpi下面干嘛?drawable目录下面button.xml文件就是selector文件。你要将图片放到hdpi目录里面,或者mdpi目录。######我就是将该 selector 文件放在 drawable-hdpi 文件夹下的,可就是没效果。######不是个例,这得看你的这个button的容器控件是否拦截了事件。######onTouchListener( ) 方法会拦截该事件的吗?######

    如果你调用 setOnTouchListener()设置了listener,取决于你实现的 onTouch的返回值

    如果是true,则事件停止传递了。

    下面是andorid View的代码片段:   

       if (onFilterTouchEventForSecurity(event)) {
                //noinspection SimplifiableIfStatement
                ListenerInfo li = mListenerInfo;
                if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                        && li.mOnTouchListener.onTouch(this, event)) {
                    return true;
                }

                if (onTouchEvent(event)) {
                    return true;
                }
            }

    ######

    引用来自“只求一醉”的答案

    如果你调用 setOnTouchListener()设置了listener,取决于你实现的 onTouch的返回值

    如果是true,则事件停止传递了。

    下面是andorid View的代码片段:   

       if (onFilterTouchEventForSecurity(event)) {
                //noinspection SimplifiableIfStatement
                ListenerInfo li = mListenerInfo;
                if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                        && li.mOnTouchListener.onTouch(this, event)) {
                    return true;
                }

                if (onTouchEvent(event)) {
                    return true;
                }
            }

    诶,你一说,我才知道,我当时的按钮的 onTouchListener( ) 事件监听,确实是 return true。
    因为我当时是用 switch ACTION_DOWN 和 ACTION_UP 来控制按钮的背景变化的,我在每个 case 里都返回 true。我以为 return true ,事件才会触发。
    其实onTouchListener方法里 return true 和 return false ,有什么区别的?

    ###### @只求一醉######最终解决方案是什么 ?######设置false难道才能继续事件?
    2020-06-07 08:55:48
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载