ArrayAdapter <myClass> nasıl kullanılır


129
ArrayList<MyClass> myList = new ArrayList<MyClass>();

ListView listView = (ListView) findViewById(R.id.list);

ArrayAdapter<MyClass> adapter = new ArrayAdapter<MyClass>(this, R.layout.row,
    to, myList.);
listView.setAdapter(adapter);

Sınıf: Sınıfım

class MyClass {
    public String reason;
    public long long_val;
}

Düzenlerde row.xml oluşturdum, ancak ArrayAdapter kullanarak ListView'da hem reason hem de long_val'i nasıl göstereceğimi bilmiyorum.

Yanıtlar:


155

Sınıfınız için özel adaptör uygulayın:

public class MyClassAdapter extends ArrayAdapter<MyClass> {

    private static class ViewHolder {
        private TextView itemView;
    }

    public MyClassAdapter(Context context, int textViewResourceId, ArrayList<MyClass> items) {
        super(context, textViewResourceId, items);
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = LayoutInflater.from(this.getContext())
            .inflate(R.layout.listview_association, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        MyClass item = getItem(position);
        if (item!= null) {
            // My layout has only one TextView
                // do whatever you want with your string and long
            viewHolder.itemView.setText(String.format("%s %d", item.reason, item.long_val));
        }

        return convertView;
    }
}

Android çerçevesine pek aşina olmayanlar için bu, burada daha ayrıntılı olarak açıklanmıştır: https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView .


2
Üzgünüm, MyClass item = items.get (position) hatayı çözüyor, değişkenler benim tarafımdan eşleşmiyor.
Sumit M Asok

1
Öğeler alanını yukarıdaki koddan kaldırdım, çünkü kolayca hatalara yol açabilir - örneğin, birisi
adaptör.clear

1
textViewResourceIdYukarıda kullanılmadığını varsaymakta haklı mıyım ?
gerrytan

8
viewHolder nereden geldi?
Gerry

2
R.layout.listview_association nedir? Bu sizin özel düzeniniz mi? Bunu android.R.layout.simple_list_item_1 ile değiştirebilir miyim?
Donato

76

Http://developer.android.com/reference/android/widget/ArrayAdapter.htmltoString() uyarınca MyClass'a bir yöntem ekleyebilirsiniz :

Ancak TextView referans alınır, dizideki her nesnenin toString () değeri ile doldurulur. Özel nesne listeleri veya dizileri ekleyebilirsiniz. Listedeki öğe için hangi metnin görüntüleneceğini belirlemek için nesnelerinizin toString () yöntemini geçersiz kılın.

class MyClass {

 @Override
 public String toString() {
  return "Hello, world.";
 }
}

20
En basit çözüm olmasına rağmen, bu (IMHO) pek iyi bir fikir değil. Üç neden: Eğer yerelleştirmeye ihtiyacınız olursa, yeniden düzenleme yapmanız gerekecektir. Bu yalnızca 1 adaptörünüz varsa çalışır, 2 farklı adaptörünüz MyClassvarsa, yeniden düzenlemeniz gerekecektir. Son olarak, sunum mantığını modellerinize bağlamak genellikle kötü bir fikirdir. Modeller, kullanıcıya nasıl sunulduğunun farkında olmamalıdır.
fernandohur

2
Bazı @ fernandohur endişelerini gidermek için, ArrayAdapter için özel bir görünüm sınıfı oluşturabilirsiniz ... bu nedenle, bir model türü , temel modeli saran (ve uygulamayı sağlayan MyClassözel bir sınıf eklemenizi gerektirirMyClassViewtoString( )
wal

Bu cevap 2011'dendi ve @ fernandohur'a katılıyorum - şimdi bunu halletmenin daha iyi yolları var.

Bunun iyi bir cevap olduğunu düşünüyorum çünkü çoğu zaman her sınıfın nesnenin adını temsil etmekten çok bir değeri vardır.
Jhon Fredy Trujillo Ortega

Kabul edilen cevap bu olmalıdır. Yalnızca yazdırılan adı ciltlemek için bir adaptörün geçersiz kılınması hatalı kodlamadır.
L.Grillo

22

Bunun en iyi yaklaşım olduğunu düşünüyorum. Genel ArrayAdapter sınıfını kullanmak ve kendi Object adaptörünüzü genişletmek aşağıdaki kadar basittir:

public abstract class GenericArrayAdapter<T> extends ArrayAdapter<T> {

  // Vars
  private LayoutInflater mInflater;

  public GenericArrayAdapter(Context context, ArrayList<T> objects) {
    super(context, 0, objects);
    init(context);
  }

  // Headers
  public abstract void drawText(TextView textView, T object);

  private void init(Context context) {
    this.mInflater = LayoutInflater.from(context);
  }

  @Override public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder vh;
    if (convertView == null) {
      convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
      vh = new ViewHolder(convertView);
      convertView.setTag(vh);
    } else {
      vh = (ViewHolder) convertView.getTag();
    }

    drawText(vh.textView, getItem(position));

    return convertView;
  }

  static class ViewHolder {

    TextView textView;

    private ViewHolder(View rootView) {
      textView = (TextView) rootView.findViewById(android.R.id.text1);
    }
  }
}

ve burada adaptörünüz (örnek):

public class SizeArrayAdapter extends GenericArrayAdapter<Size> {

  public SizeArrayAdapter(Context context, ArrayList<Size> objects) {
    super(context, objects);
  }

  @Override public void drawText(TextView textView, Size object) {
    textView.setText(object.getName());
  }

}

ve son olarak, nasıl başlatılır:

ArrayList<Size> sizes = getArguments().getParcelableArrayList(Constants.ARG_PRODUCT_SIZES);
SizeArrayAdapter sizeArrayAdapter = new SizeArrayAdapter(getActivity(), sizes);
listView.setAdapter(sizeArrayAdapter);

TextView düzen yerçekimi özelleştirilebilir ArrayAdapter ile bir Gist oluşturdum:

https://gist.github.com/m3n0R/8822803


1
Kodunuzu gerçekten çok beğendim, ancak android.content.res.Resources $ NotFoundException: Kaynak Kimliği # 0x0 ile neden çöktüğünü anlamam biraz zaman aldı. Süper (.., 0, ..) üzerinde jenerik bağdaştırıcı çağrınız var, burada 0 aslında bir düzen kaynağıdır, bu yüzden başka bir şeye değiştirilmelidir .. Ayrıca,
özünüz

Sonunda çok fazla değişiklik yaptım - açılır menünün düzeni gösterilen öğenin düzeninden farklıydı, drawText tıklanan öğelerde değil, yalnızca döndürücü başlığında çağrıldı ..
Ev0oD

Bu, jenerik adaptör olarak geçerli olmalıdır. Problemi çözebilir misin?
cesards

Evet, çalıştırdım. İstediğimden biraz farklı bir şey için çözüm sağladığınızı fark ettim, ancak kodunuzu başlangıç ​​noktası olarak kullanabildim ve benim için istediğim şeyi bana yapacak şekilde değişiklikler yapabildim. Bu kod parçası için teşekkürler.
Ev0oD

Bu, varsayılan olarak sağlanmalıdır.
Goddard

6

ArrayAdapter öğesini alt sınıflandırın ve görüntülemek istediğiniz içeriği içeren kendi görünümünüzü döndürmek için getView () yöntemini geçersiz kılın .


5

Anne sınıfını genişletmekle uğraşmak istemiyorsanız ArrayAdapter'ı nasıl kullanacağınıza dair hızlı ve kirli bir örnek:

class MyClass extends Activity {
    private ArrayAdapter<String> mAdapter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mAdapter = new ArrayAdapter<String>(getApplicationContext(),
            android.R.layout.simple_dropdown_item_1line, android.R.id.text1);

        final ListView list = (ListView) findViewById(R.id.list);
        list.setAdapter(mAdapter);

        //Add Some Items in your list:
        for (int i = 1; i <= 10; i++) {
            mAdapter.add("Item " + i);
        }

        // And if you want selection feedback:
        list.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //Do whatever you want with the selected item
                Log.d(TAG, mAdapter.getItem(position) + " has been selected!");
            }
        });
    }
}
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.