谁在ArrayAdapter中调用getView()?

时间:2015-09-04 22:32:28

标签: java android listview

我正在为ListView编写自己的适配器,但我遇到了一些概念问题。首先,这就是我写的:

public class MyArrayAdapter extends ArrayAdapter<String> {
    private final Context context;
    private final int parent;
    private final String[] values;

    public MyArrayAdapter(Context context, int resourceid, String[] values) {
        super(context, -1, values);
        this.context = context;
        this.parent = resourceid;
        this.values = values;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
        TextView textView = (TextView) rowView.findViewById(R.id.label);
        ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
        textView.setText("abcde lorem ipsum");
        String s = values[position];
        imageView.setImageResource(R.drawable.no);

        return rowView;
    }
}

正如大家们所看到的,我在构造函数中添加了resourceid作为参数,因为this page告诉我必须使用3个参数。但是,在this article的3.3示例中,当它编写自定义适配器时,它使用2个参数作为构造函数。但是如果我没有在构造函数中将R.layout.rowlayout作为参数传递,那么getView如何知道谁是ViewGroup parent?我的意思是,必须以某种方式调用getView,并且必须将父对象传递给它。但是班级怎么知道谁是父母?

另外,android页面指示我这样调用它:

MyArrayAdapter<String> adapter = new MyArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);

但我最终不得不取消<String>并离开它:

MyArrayAdapter adapter = new MyArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);

为什么?

是不是因为文章在不使用<String>的情况下扩展了课程?像这样:

public class MyArrayAdapter extends ArrayAdapter<String> {

另外,由于我重写了这个类,为什么我需要使用super调用原始构造函数?

2 个答案:

答案 0 :(得分:0)

我认为你误解了一些基本概念。首先,ArrayAdapter需要3个构造函数参数,从中继承的类可以包含任意多个。此外,您将列表项的资源ID传递给它,而不是父项的资源ID。

ArrayAdapter的基本思想是这样的:

public class MyArrayAdapter extends ArrayAdapter<String> {

    public MyArrayAdapter(Context context, String[] values) {
        super(context, R.layout.rowlayout, values);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = super.getView(position, convertView, parent);
        ...

        return rowView;
    }
}

ArrayAdapter.getView()将返回传递给构造函数的布局实例。

其次:适配器连接到ListViewListView知道包含列表的视图的布局,因此知道每行的父视图。 ListView也是在适配器上调用getView()的那个。只需在getView中添加一个断点,就可以看到谁在调用它。

答案 1 :(得分:0)

正在进行中,

即使您创建了一个MyArrayAdapter对象,在您将ListView引用设置为适配器之前,它也不会执行此类中的任何方法。所以这个ViewGroup parent来自ListView引用,根据父参数相应地膨胀元素(Parent将是listview)。

如果要为ListView中的每个元素使用完全不同的自定义布局,则不希望将资源ID传递给适配器。

    public MyArrayAdapter(Context context, String[] values) {
        super(context, 0, values);
        this.context = context;

        this.values = values;
    }

因为现在您正在为元素使用自定义布局,然后根据需要使用以下内容进行充气,

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.rowlayout, parent, false);

现在是棘手的部分。

如果您确实要从构造函数传递resourceid,

如下,

        public MyArrayAdapter(Context context, int resourceid, String[] values) {
            super(context, 0, values);// 0 is just a filler here,
            this.context = context;
            this.resourceid= resourceid;
            this.values = values;
        }

你的自定义类对我来说更通用(这与android无关)

因为,

你可以在这里使用,

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View rowView = inflater.inflate(this.resourceid, parent, false);

您还应该阅读this回答来掌握ArrayAdapter的想法。

编辑:

我没有看到它的到来,  不要错过了解以下

this.parent = resourceid;

用,

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

父。

从传递ViewGroup parent(基本上没有关系)到超级构造函数有resourceid的推导,ViewGroup parent来自ListView ListView使用适配器设置引用。