Android 以编程方式替换选择器图像

Android 以编程方式替换选择器图像,android,imageview,drawable,Android,Imageview,Drawable,我有一个ImageView,它将可绘制图像资源设置为选择器。如何以编程方式访问选择器并更改高亮显示和非高亮显示状态的图像 以下是选择器的代码: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iconSelector"> <!-- pressed -->

我有一个ImageView,它将可绘制图像资源设置为选择器。如何以编程方式访问选择器并更改高亮显示和非高亮显示状态的图像

以下是选择器的代码:

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


我希望能够用其他图像替换
btn_图标\u hl
btn_图标

据我所知(我自己也尝试过类似的操作),在StateListDrawable已经定义之后,无法修改单个状态。但是,您可以通过以下代码定义一个新的:

StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
    getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {android.R.attr.state_focused},
    getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
    getResources().getDrawable(R.drawable.normal));
imageView.setImageDrawable(states);

你可以在手上放两个,或者根据需要创建一个不同的。

我遇到了同样的问题,并进一步解决了这个问题。但是,唯一的问题是不能在xml中指定NavStateListDrawable,因此必须通过代码设置UI元素的背景。然后必须重写onStateChange方法,以确保每次更改主绘图表的级别时,也会更新子级别列表的级别

构建NavStateListDrawable时,必须传入要显示的图标级别

public class NavStateListDrawable extends StateListDrawable {

    private int level;

    public NavStateListDrawable(Context context, int level) {

        this.level = level;
        //int stateChecked = android.R.attr.state_checked;
        int stateFocused = android.R.attr.state_focused;
        int statePressed = android.R.attr.state_pressed;
        int stateSelected = android.R.attr.state_selected;

        addState(new int[]{ stateSelected      }, context.getResources().getDrawable(R.drawable.nav_btn_pressed));
        addState(new int[]{ statePressed      }, context.getResources().getDrawable(R.drawable.nav_btn_selected));
        addState(new int[]{ stateFocused      }, context.getResources().getDrawable(R.drawable.nav_btn_focused));

        addState(new int[]{-stateFocused, -statePressed, -stateSelected}, context.getResources().getDrawable(R.drawable.nav_btn_default));


    }

    @Override
    protected boolean onStateChange(int[] stateSet) {

        boolean nowstate = super.onStateChange(stateSet);

        try{
            LayerDrawable defaultDrawable = (LayerDrawable)this.getCurrent();


            LevelListDrawable bar2 =  (LevelListDrawable)defaultDrawable.findDrawableByLayerId(R.id.nav_icons);
            bar2.setLevel(level);
        }catch(Exception exception)
        {

        }

        return nowstate;
    }
}
对于所有不同的导航按钮可绘制状态,我有如下内容

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

   <item android:drawable="@drawable/top_bar_default" >

   </item>

    <item android:id="@+id/nav_icons" android:bottom="0dip">
        <level-list xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:maxLevel="0" >
                <bitmap
                    android:src="@drawable/top_bar_icon_back"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="1" >
                <bitmap
                    android:src="@drawable/top_bar_icon_nav"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="2" >
                <bitmap
                    android:src="@drawable/top_bar_icon_settings"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="3" >
                <bitmap
                    android:src="@drawable/top_bar_icon_search"
                    android:gravity="center" />
            </item>
        </level-list>

    </item>

</layer-list>


我本来想把这个作为一个问题和答案发布,但既然你已经问了这个问题,那就来吧。注意,这为您节省了大量xml文件定义。我从大约50-100个xml定义降到了大约4个

有两个选择器并交换它们不是更容易吗?问题是,最终可能会有数百个xml文件。navstatelistdrawable代码有效地使选择器xml冗余。嗨,emilie,是否有可能drawables作为按钮背景不会因为任何原因第一次出现。目前,我遇到的问题是,我需要触摸按钮区域以显示背景,或者切换出并切换回活动。(这只发生在hdpi屏幕上,但在我的mdpi上效果很好)。我相信其他人也可能有这个问题。您的代码是否针对所有屏幕密度进行了测试?嗨,不,这是很久以前编写的,当时只针对一台设备。我不确定会出现什么样的问题,但据我所知,多个屏幕密度和布局不应该出现问题。谢谢,我不知道我做错了什么,但最后我得到了以下结果:buttonStates=new StateListDrawable();buttonStates.addState(新的int[]{statePressed},ApplicationConstants.moduleImageLoader.findImageByName(drawable_pressed));buttonStates.addState(新int[]{-stateFocused,-statePressed,-stateSelected},ApplicationConstants.moduleImageLoader.findImageByName(drawable_normal));这是我第一次看到设置为false的状态必须使用负值。文件对此不是很清楚。谢谢你的提示!我无法将此添加到图像视图中。setState在上面不可用。实际上我找到了它,它的setImageDrawable()非常感谢它的工作,为我保存了大约40个xml文件!因此,我有另一个与此相关的注释。我希望你能回答。我在自定义控件内的ImageView上设置了此选择器。自定义控件还有一个选择器作为背景。因此,整个控件的选择器工作,而ImageView选择器不工作。我做错什么了吗?有序列吗?不客气!是的,我不知道为什么我要设置状态,应该是可设置图像绘制的,你是对的。根据您的另一个问题,我建议发布一个新问题,其中包含自定义控件及其选择器的代码,我不确定该问题的答案。我使用的是相同的代码。始终保留我在--->new int[]{}状态中指定的映像。我哪里错了??