Заменить изображения селектора программно - PullRequest
115 голосов
/ 15 января 2011

У меня есть 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_icon_hl и btn_icon другими изображениями.

Ответы [ 2 ]

244 голосов
/ 15 января 2011

Насколько мне удалось найти (я сам пытался сделать что-то подобное), нет способа изменить одно состояние после того, как StateListDrawable уже определен.Однако вы можете определить NEW с помощью кода:

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);

И вы можете просто оставить два из них под рукой или создать другой, как вам нужно.

6 голосов
/ 15 января 2011

У меня была та же проблема, и я пошёл дальше, чтобы ее решить. Однако единственная проблема заключается в том, что вы не можете указать NavStateListDrawable в xml, поэтому вы должны установить фон вашего элемента пользовательского интерфейса с помощью кода. Затем метод 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!

...