List Adapter setting - How can I not to repeat the list item layout resource?

霸气de小男生 提交于 2019-12-17 15:04:14

问题


I have made a ListView with an ArrayAdapter. It works. But I had to put the resource id for the item layout twice: in the adapter definition and in the getView, in the case when the View parameter is null.

// --------------------------------------------here is the FIRST use
lvShows.setAdapter(new ArrayAdapter<TvShow>(this, R.layout.show_row, allKnownShows) {
    @Override
    public View getView(int position, final View rowView, ViewGroup parent) {
        LinearLayout showView;
        if (rowView == null) {

            // --------------------------------- here is the SECOND use
            showView = (LinearLayout) inflater.inflate(R.layout.show_row, parent, false);
        }
        else {
            showView = (LinearLayout) rowView;
        }
        ((TextView) showView.getChildAt(0)).setText(time));
        ((TextView) showView.getChildAt(1)).setText(name);
        return showView;
    }
});

Such style is disgustful, of course. Could you kindly advise, what am I understanding wrong and how can I use the resource only once?

If creating a new ArrayAdapter I am setting the layout id, it should know it and use somehow. How could I reach it? Or better I would expect the Adapter to create item views automatically. Again - how can I use it?

What ArrayAdapter does with that resource we feed to it when creating a new one? All its constructors take the item resource and we manage this resource and inflate it "by hand". It is not the effective way.


回答1:


You can override ArrayAdapter constructor and call super :

public ArrayAdapter<T>(Context context, TheDataType data) {
   super(context, R.layout.show_row, data);
 }

And store the id in a ArrayAdapter member variable. It avoid the adapter "user" to know what is the view needed for the adapter.

Or you can use a BaseAdapter.




回答2:


I had looked into the source code of the ArrayAdapter, and it already does all this stuff about view creation:

// citation from public class ArrayAdapter<T>
private View createViewFromResource(int position, View convertView, ViewGroup parent,
        int resource) {
    View view;
    TextView text;
    if (convertView == null) {
        view = mInflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }

So, we should simply use it:

lvShows.setAdapter(new ArrayAdapter<TvShow>(this, 
                                            R.layout.show_row, 
                                            R.id.nameField, 
                                            allKnownShows){
public View getView(int position, final View convertView, ViewGroup parent) {
    LinearLayout showView = (LinearLayout) super.getView(position,  convertView, parent);

    setAnythingForItem(showView);

    return showView;
}

Attention: we have changed the constructor!

ArrayAdapter allows to use no-TextView item layout. But if it is not TextView itself, it should have one and the id of this very inner TextView field should be given to the constructor as the third parameter. ArrayAdapter needs it to be set, to write there Strings if the array connected to it has String elements.

It wants a TextView always, even if it doesn't need it really, if the array consists of Objects, not Strings. Otherway it checks the item layout for being a TextView and if it is not, throws an error.



来源:https://stackoverflow.com/questions/9531531/list-adapter-setting-how-can-i-not-to-repeat-the-list-item-layout-resource

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!