ListView'da birden çok görünüm için özel Android Bağdaştırıcılı ArrayIndexOutOfBoundsException


185

ListView her öğe farklı bir görünüm (bir bağlantı, geçiş veya radyo grubu) olabilir, çünkü ListView için özel bir bağdaştırıcı oluşturmak çalışıyorum, ancak ListView kullanan etkinliği çalıştırmaya çalıştığınızda bir hata alıyorum ve uygulama durur. Uygulama Android 1.6 platformu için hedeflenmiştir.

Kod:

public class MenuListAdapter extends BaseAdapter {
 private static final String LOG_KEY = MenuListAdapter.class.getSimpleName();

 protected List<MenuItem> list;
 protected Context ctx;
 protected LayoutInflater inflater;

 public MenuListAdapter(Context context, List<MenuItem> objects) {
  this.list = objects;
  this.ctx = context;
  this.inflater = (LayoutInflater)this.ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  Log.i(LOG_KEY, "Position: " + position + "; convertView = " + convertView + "; parent=" + parent);
  MenuItem item = list.get(position);
  Log.i(LOG_KEY, "Item=" + item );

        if (convertView == null)  {
            convertView = this.inflater.inflate(item.getLayout(), null);
        }

        return convertView;
 }

 @Override
 public boolean areAllItemsEnabled() {
  return false;
 }

 @Override
 public boolean isEnabled(int position) {
  return true;
 }

 @Override
 public int getCount() {
  return this.list.size();
 }

 @Override
 public MenuItem getItem(int position) {
  return this.list.get(position);
 }

 @Override
 public long getItemId(int position) {
  return position;
 }

 @Override
 public int getItemViewType(int position) {
  Log.i(LOG_KEY, "getItemViewType: " + this.list.get(position).getLayout());
  return this.list.get(position).getLayout();
 }

 @Override
 public int getViewTypeCount() {
  Log.i(LOG_KEY, "getViewTypeCount: " + this.list.size());
  return this.list.size();
 }

}

Aldığım hata:

    java.lang.ArrayIndexOutOfBoundsException
  at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:3523)
  at android.widget.ListView.measureHeightOfChildren(ListView.java:1158)
  at android.widget.ListView.onMeasure(ListView.java:1060)
  at android.view.View.measure(View.java:7703)

Uygulamanın geri döndüğünü biliyorum getViewve her şey yolunda görünüyor.

Buna neyin sebep olabileceğine dair herhangi bir fikir takdir edilecektir.

Teşekkürler,

-Dan


Merhaba Dan, getCount ListView görüntülenecek toplam öğeleri var emin misiniz ??? public int getCount () {dönüş this.list.size (); }
Jorgesys

4
Daha az açıklayıcı bir hata mesajı
bulamadılar

Yanıtlar:


515

İade ettiğiniz öğe görünümü türü

getItemViewType()olduğunu >= getViewTypeCount().


24
Bu iğrenç. Hata ayıklamanın yolu yok. Çok teşekkürler, Romain Guy açıkladığı için.
Yar

113
başka bir şey, ViewType 0'dan başlamalıdır.
HelmiB

16
Şimdiye kadar cevap için 38 oy aldınız, bu yüzden bu mükemmel bir cevap olabilir, ancak sorunu ve nasıl çözüleceğini açıklamak için lütfen biraz daha metin ekleyin ... çünkü hala bundan çok anlayamıyorum.
Chirag Patel

15
Güdük olanlar için, ViewType sıfır tabanlı bir dizin döndürmelidir. örneğin (0, 1, 2 ...). benim durumumda ... ViewType için R.layout ... yeniden kullanmaya çalıştı. dahili olarak ViewType değeri geri dönüşüm havuzu için bir dizin olarak değil, bir anahtar olarak kullanılıyor sanırım.
Samuel

2
Bu hatayı, her zamanki gibi, belgelerinde bu hayati titbitten bahsetmekten rahatsız olmayan Android geliştiricilerinin aksine açıkladığınız için teşekkür ederiz.
WKS

17

Kabul edilen cevap doğrudur. Bu sorunu önlemek için yapıyorum:

public enum FoodRowType {
    ONLY_ELEM,
    FIRST_ELEM,
    MID_ELEM,
    LAST_ELEM
}

@Override
public int getViewTypeCount() {
    return FoodRowType.values().length;
}

@Override
public int getItemViewType(int position) {
    return rows.get(position).getViewType();  //returns one of the above types
}

Sadece getItemViewTypeint
dVaffection

0

Sorun getItemType değeri yanlış olduğunda gelir. ViewTypeCount () - 1 elde etmek için bu değer bir tamsayı olmalı ve 0'dan olmalıdır.


-3

Bunun nedeni büyük olasılıkla getItemViewType yönteminin yanlış değerleri döndürmesidir! Liste görünümündeki her satır bir Görünümdür. GetItemViewType scrooling sırasında View sayısından daha fazla ulaşmak.

Ne yapalım? Sorun nasıl önlenir?

İlk olarak liste görünümünüzde ilk olarak gösterilen görünümü (satır) belirleyin.

    @Override
    public int getItemViewType(int position) {
        return choseType(position);//function to use modular equation
    }
    @Override
    public int getViewTypeCount() {
        return 10;
    }

Bu örnekte on görünüm vardır (10 satır).

private  int choseType(int position){
    if(position%10==0)
        return 0;
    else if(position%10==1)
        return 1;
    else if(position%10==2)
        return 2;
    else if(position%10==3)
        return 3;
    else if(position%10==4)
        return 4;
    else if(position%10==5)
        return 5;
    else if(position%10==6)
        return 6;
    else if(position%10==7)
        return 7;
    else if(position%10==8)
        return 8;
    else
        return 9;


}

Önemli

Bazı kullanıcılar stackoverflow bu yöntemle ilgili başka bir sorudan bahsetti

Tooglebutton gibi public int getViewTypeCount () ve public int getItemViewType (int pozisyon) düzeltmesi otomatik olarak scrooling'de durum kontrolünü doğru olarak etkinleştirir .. bu büyük yanlıştır .

toogleButton.setChecked(false);

getView geçersiz kılma yöntemi.

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.