ArrayAdapter <myClass> का उपयोग कैसे करें


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

वर्ग: MyClass

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

मैंने लेआउट में row.xml बनाया है, लेकिन ArrayAdapter का उपयोग करके ListView में कारण और long_val दोनों को दिखाने का तरीका नहीं जानता।

जवाबों:


155

अपनी कक्षा के लिए कस्टम एडॉप्टर लागू करें:

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

एंड्रॉइड फ्रेमवर्क से बहुत परिचित नहीं लोगों के लिए, इसे यहां बेहतर तरीके से समझाया गया है: https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView


2
क्षमा करें, MyClass आइटम = items.get (स्थिति) त्रुटि को हल करता है, मेरे द्वारा चरों को बेमेल करता है।
सुमित एम असोक

1
मैंने आइटम कोड को ऊपर के कोड से हटा दिया है, क्योंकि यह आसानी से त्रुटियों को जन्म दे सकता है - उदाहरण के लिए यदि कोई
एडेप्टर .clear

1
क्या मैं यह मानने में सही हूं कि textViewResourceIdऊपर प्रयोग नहीं किया गया है?
gerrytan

8
व्यूहोल कहां से आया?
गेरी

2
R.layout.listview_association क्या है? क्या आपका कस्टम लेआउट है? क्या मैं इसे android.R.layout.simple_list_item_1 से बदल सकता हूं?
डोनैटो

76

आप केवल toString()MyClass, प्रति http://developer.android.com/reference/android/widget/ArrayAdapter.html : में एक विधि जोड़ सकते हैं :

हालाँकि TextView संदर्भित है, यह सरणी में प्रत्येक ऑब्जेक्ट के toString () से भरा होगा। आप कस्टम ऑब्जेक्ट्स की सूची या सरणियाँ जोड़ सकते हैं। सूची में आइटम के लिए कौन सा पाठ प्रदर्शित किया जाएगा, यह निर्धारित करने के लिए अपनी वस्तुओं के स्ट्रींग () विधि को ओवरराइड करें।

class MyClass {

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

20
हालांकि सबसे सरल समाधान, यह (IMHO) बहुत अच्छा विचार नहीं है। तीन कारण: यदि आपको कभी भी स्थानीयकरण की आवश्यकता होती है, तो आपको रिफ्लेक्टर करना होगा। यह केवल तभी काम करता है जब आपके पास 1 एडॉप्टर हो, यदि आपके पास 2 अलग-अलग एडेप्टर हैं MyClass, तो आपको wil को रिफलेक्टर करना होगा। अंत में, आमतौर पर अपने मॉडलों के लिए प्रस्तुति तर्क को बाँधना एक बुरा विचार है। मॉडल को इस बात की जानकारी नहीं होनी चाहिए कि उन्हें उपयोगकर्ता के सामने कैसे प्रस्तुत किया जाए।
फर्नान्डोहुर

2
@fernandohur की कुछ चिंताओं को दूर करने के लिए आप केवल ArrayAdapter के लिए एक समर्पित विचार वर्ग बना सकते हैं ... इसलिए एक प्रकार के मॉडल वर्ग के MyClassलिए आपको एक समर्पित वर्ग जोड़ने की आवश्यकता होगी, MyClassViewजो अंतर्निहित मॉडल को लपेटता है (और toString( )कार्यान्वयन प्रदान करता है
Wal

यह जवाब 2011 से था, और मैं @fernandohur से सहमत हूं - अब इसे संभालने के बेहतर तरीके हैं।

मुझे लगता है कि यह एक अच्छा जवाब है क्योंकि, बहुत बार प्रत्येक वर्ग में वस्तु के नाम का प्रतिनिधित्व करने की तुलना में एक प्रायश्चित होता है।
झॉन् फ्रेडे ट्रुजिलो ओर्टेगा

यह स्वीकृत उत्तर होना चाहिए। केवल एडॉप्टर को ओवरराइड करके मुद्रित नाम को खराब करना कोडिंग है।
एल। गिलोइल

22

मुझे लगता है कि यह सबसे अच्छा तरीका है। जेनेरिक ArrayAdapter क्लास का उपयोग करना और अपने स्वयं के ऑब्जेक्ट एडेप्टर का विस्तार करना इस प्रकार सरल है:

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

और यहां आपका एडॉप्टर (उदाहरण):

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

}

और अंत में, इसे कैसे आरंभ करें:

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

मैंने TextView लेआउट गुरुत्वाकर्षण अनुकूलन ArrayAdapter के साथ एक Gist बनाया है:

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


1
मुझे आपका कोड बहुत पसंद आया, लेकिन मुझे यह पता लगाने में थोड़ा समय लगा, कि यह android.content.res.es के साथ क्यों दुर्घटनाग्रस्त हो रहा था। $ NotFoundException: रिसोर्स आईडी # 0x0। आप सुपर (.., 0, ..) पर अपने जेनेरिक अडैप्टर कॉल में हैं, जहां 0 वास्तव में एक लेआउट संसाधन है, जो मौजूद नहीं है, इसलिए इसे किसी और चीज़ में बदलना होगा। इसके अलावा, आपका
जीआईएस

अंत में मैंने बहुत कुछ बदलना समाप्त कर दिया - ड्रॉपडाउन मेनू का लेआउट दिखाए गए आइटम के लेआउट से अलग था, ड्रोटेक्स्ट को केवल स्पिनर हेडर पर बुलाया गया था, क्लिक किए गए उसके आइटम पर नहीं ..
Ev0oD

यह जेनेरिक एडॉप्टर के रूप में मान्य होना चाहिए। क्या आप समस्या को हल कर सकते हैं?
cesards

हाँ, मैंने यह काम किया है। मैंने महसूस किया कि आप कुछ अलग करने के लिए एक समाधान प्रदान करते हैं, फिर मैं जो चाहता था, लेकिन मैं आपके कोड को एक शुरुआती बिंदु के रूप में उपयोग करने में सक्षम था और इस तरह से संशोधन कर सकता था जैसा कि वह मेरे लिए करता था जो मैं चाहता था। कोड के इस टुकड़े के लिए धन्यवाद।
Ev0oD

यह डिफ़ॉल्ट रूप से प्रदान किया जाना चाहिए।
गोडार्ड

6

ArrayAdapter को उपवर्गित करें और अपने स्वयं के दृश्य को वापस करने के लिए विधि getView () को ओवरराइड करें जिसमें वह सामग्री है जिसे आप प्रदर्शित करना चाहते हैं।


5

यहां एक त्वरित और गंदा उदाहरण दिया गया है कि अगर आप मदर क्लास को बढ़ाने के साथ खुद को परेशान नहीं करना चाहते हैं तो एक ArrayAdapter का उपयोग कैसे करें:

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!");
            }
        });
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.