Reputation: 2925
I have a class that extends ArrayList
. To show its contents in a ListView
widget, I extend ArrayAdapter
.
The ListView
has to show 2 properties for each item of my extended ArrayList
. For that reason, I inflate a custom layout in the getView()
method of my extended ArrayAdapter
.
The Android API specifies 6 constructors for ArrayAdapter
, and all of them have one common argument textViewResourceId
, which is specified as either 'a TextView in a layout', or 'a layout containing a TextView'.
Why that reference to just one TextView
, if in the method getView()
we can populate more than one? Which one should be the TextView
to be passed to the constructor in case more than one are being populated?
Upvotes: 2
Views: 1067
Reputation: 11518
The Android API specifies 6 constructors for
ArrayAdapter
, and all of them have one common argumenttextViewResourceId
, which is specified as either 'a TextView in a layout', or 'a layout containing a TextView'.
These are known as default constructors, and are meant to provide a simple implementation for those looking for a One-Text-View-Based ListView.
Since you are creating a custom class that extends ArrayAdapter
, you don't have to use the same constructors, you can create your own.
For instance:
public CustomArrayAdapter (Context context,
int TextViewRes, int OtherTextViewRes) {}
And so forth an on, as long as you override the required methods, you'll be just fine.
Upvotes: 1
Reputation: 3542
I've found the ArrayAdapter isn't very extendable beyond the very basic use cases. The example you've noted about constructors is one example.
A suggestion is that you actually extend BaseAdapter
instead and implement something like the following:
public class MyArrayAdapter<T> extends BaseAdapter {
private Context mContext;
private List<T> mItems = new ArrayList<T>();
public MyArrayAdapter(Context context, ArrayList<T> items) {
mContext = context;
mItems = items;
}
public int getCount() {
return mItems .size();
}
public Object getItem(int position) {
return mItems .get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// your existing code
}
}
Upvotes: 0
Reputation: 5876
You're right, this is a little bit confusing, but what I think is going on is that the constructors are describing the behavior for the ArrayAdapter class if you do not override getView()
. That is, the default behavior of getView()
.
From the docs:
A concrete BaseAdapter that is backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView. If you want to use a more complex layout, use the constructors that also takes a field id. That field id should reference a TextView in the larger layout resource.
However the TextView is referenced, it will be filled with the toString() of each object in the array. You can add lists or arrays of custom objects. Override the toString() method of your objects to determine what text will be displayed for the item in the list.
So, the ArrayAdapter
class will take in an array of objects, and each object will have just one String to be displayed, generated by calling that object's toString()
method. That is why all of the constructors require you pass arguments to point to one TextView, to display the single String for that ListItem. As described above, the two ways to do that are to: 1. Specify a single TextView by id or 2. Pass the id of a more complex layout and also the id of the chosen TextView within that layout to display the String.
Therefore, if you're extending ArrayList
, I think that all bets are off, you're going to be overriding the default behavior for getView
and you could choose to display 6 Strings in 6 different TextViews if you wanted, that's up to you.
Upvotes: 1