Ich habe eine ImageView, die eine zeichenbare Bildressource auf einen Selektor gesetzt hat. Wie greife ich programmgesteuert auf den Selektor zu und ändere die Bilder des hervorgehobenen und nicht hervorgehobenen Zustands?
Hier ist ein Auswahlcode:
<?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>
Ich möchte ersetzen können btn_icon_hl
und btn_icon
mit anderen Bildern.
Soweit ich feststellen konnte (ich habe selbst versucht, etwas Ähnliches zu tun), gibt es keine Möglichkeit, einen einzelnen Status zu ändern, nachdem das StateListDrawable bereits definiert wurde. Sie können jedoch einen NEUEN durch Code definieren:
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);
Und Sie können einfach zwei davon zur Hand haben oder bei Bedarf ein anderes erstellen.
Ich hatte das gleiche Problem und ging einen Schritt weiter, um es zu lösen. Das einzige Problem ist jedoch, dass Sie das NavStateListDrawable nicht in XML angeben können, sodass Sie den Hintergrund Ihres UI-Elements durch Code festlegen müssen. Die onStateChange-Methode muss dann überschrieben werden, um sicherzustellen, dass jedes Mal, wenn die Ebene des Haupt-Drawables geändert wird, auch die Ebene der untergeordneten Ebenenliste aktualisiert wird.
Beim Erstellen des NavStateListDrawable müssen Sie die Ebene des Symbols übergeben, das Sie anzeigen möchten.
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;
}
}
Für all die verschiedenen zeichbaren Zustände der Navigationsschaltfläche habe ich so etwas wie das Folgende.
<?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="https://stackoverflow.com/questions/4697528/@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>
Ich wollte dies als Frage und Antwort posten, aber da Sie genau die Frage gestellt haben, bitte hier. Beachten Sie, dass Sie dadurch eine Menge XML-Dateidefinitionen sparen. Ich ging von ungefähr 50-100 XML-Definitionen auf ungefähr 4 herunter!.
Wäre es nicht einfacher, zwei Selektoren zu haben und sie auszutauschen?
– große Steine
15. Januar 2011 um 1:46 Uhr
Das Problem dabei ist, dass Sie am Ende Hunderte von XML-Dateien haben können.
– Emil
15. Januar 2011 um 14:06 Uhr