Seçici görüntüleri programla değiştirin


116

Seçiciye ayarlanmış çekilebilir bir görüntü kaynağına sahip bir ImageView'ım var. Seçiciye programlı olarak nasıl erişirim ve vurgulanan ve vurgulanmayan durumun görüntülerini nasıl değiştiririm?

İşte bir seçici kodu:

<?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>

Diğer resimlerle btn_icon_hlve değiştirebilmek istiyorum btn_icon.


iki seçiciye sahip olmak ve onları değiştirmek daha kolay olmaz mıydı?
bigstones

2
Bununla ilgili sorun, yüzlerce xml dosyasıyla sonuçlanabilir.
Emile

Yanıtlar:


244

Bulabildiğim kadarıyla (kendime benzer bir şey yapmayı denedim), StateListDrawable zaten tanımlandıktan sonra tek bir durumu değiştirmenin bir yolu yok. Bununla birlikte, kod aracılığıyla YENİ bir tane tanımlayabilirsiniz:

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

Ve bunlardan ikisini elinizin altında tutabilir veya ihtiyaç duyduğunuzda farklı bir tane yaratabilirsiniz.


1
Bunu bir resim görünümüne ekleyemedim. setState üzerinde mevcut değil.
dropsOfJupiter

2
aslında buldum, setImageDrawable () Çok teşekkür ederim işe yaradı ve beni yaklaşık 40 xml dosyası kurtardı!
dropsOfJupiter

2
Bu yüzden bununla ilgili başka bir notum var. Cevap vermeni umuyordum. Bu seçiciyi Özel Kontrolün içindeki ImageView üzerinde ayarladım. Özel kontrolün arka plan olarak bir seçici de vardır. Dolayısıyla, tüm kontrolün seçicisi çalışırken ImageView seçici çalışmaz. Yanlış yaptığım bir şey mi var? Bir dizi var mı?
dropsOfJupiter

1
Rica ederim! Evet neden setState'i koyduğumu bilmiyorum, setImageDrawable olmalı, haklısın. Diğer sorunuza göre, özel kontrolünüz ve seçiciniz için kodla yeni bir soru göndermenizi öneririm, bunun cevabından emin değilim.
Kevin Coppock

3
aynı kodu kullanıyorum. her zaman ----> new int [] {} durumunda belirttiğim görüntü kalır. nerede yanılmışım?
KK_07k11A0585

6

Aynı sorunu yaşadım ve çözmek için bir adım daha ileri gittim. Ancak tek sorun, NavStateListDrawable'ı xml'de belirtememenizdir, bu nedenle UI öğenizin arka planını kod aracılığıyla ayarlamanız gerekir. OnStateChange yöntemi daha sonra, ana çekilebilir seviyenin her değiştiğinde, alt seviye listesinin seviyesini de güncellemenizi sağlamak için geçersiz kılınmalıdır.

NavStateListDrawable'ı oluştururken, görüntülemek istediğiniz simge düzeyini geçmeniz gerekir.

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

Tüm farklı gezinme düğmesinin çekilebilir durumları için aşağıdaki gibi bir şeyim var.

<?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>

Bunu bir soru cevap olarak gönderecektim, ama soruyu sorduğunuza göre, işte buyrun. Unutmayın, bu size çok fazla xml dosya tanımından tasarruf sağlar. 50-100 xml tanımından yaklaşık 4'e düştüm !.


Navstatelistdrawable kodu, seçici xml'yi etkili bir şekilde gereksiz hale getirir.
Emile

Merhabalar emilie, Herhangi bir sebepten ötürü bir düğme arka planı olarak çekilebilir öğelerin ilk kez görünmeme olasılığı var mı? Şu anda, arka planın görünmesi için düğme alanına dokunmam veya geçiş yapıp etkinliğe geri dönmem gereken yerde sorunu alıyorum. (Bu yalnızca bir hdpi ekranında olur, ancak mdpi'mde iyi çalışır). Başkalarının da bu sorunu yaşayabileceğine inanıyorum. Kodunuz tüm ekran yoğunlukları için test edildi mi?
ryvianstyron

Merhaba, hayır, bu bir süre önce yazılmıştı ve o zamanlar sadece bir cihaz içindi. Birden fazla ekran yoğunluğu ve düzeninin bir sorun teşkil etmemesi gerektiğini bildiğim sürece ne tür bir sorunun ortaya çıkabileceğinden emin değilim.
Emile

Teşekkürler Neyi yanlış yaptığımı tam olarak bilmiyorum ama sonunda şunlara sahiptim: buttonStates = new StateListDrawable (); buttonStates.addState (yeni int [] {statePressed}, ApplicationConstants.moduleImageLoader.findImageByName (drawable_pressed)); buttonStates.addState (new int [] {- ​​stateFocused, -statePressed, -stateSelected}, ApplicationConstants.moduleImageLoader.findImageByName (drawable_normal));
ryvianstyron

1
Yanlış olarak ayarlanmış durumlar için negatif değerlerin kullanılması gerektiğini gördüğüm ilk yer burası. Belgeler bu konuda çok net değil. Bahşiş için teşekkürler!
eocanha
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.