0

I'm writing my own adapter for a ListView, but I'm having trouble with some concepts. First of all, that's what I wrote:

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

As you guys can see, I added the resourceid as an argument in the constructor, because this page tells me that it must take 3 arguments. However, at the 3.3 example of this article, when it writes a custom adapter, it uses 2 arguments for the constructor. But if I don't pass R.layout.rowlayout as an argument in the constructor, how getView know who is the ViewGroup parent? I mean, somehow getView must be called, and the parent object must be passed to it. But how the class knows who is the parent?

Also, the android page instructs me to call it like this:

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

But I end up having to take <String> off and leave it like this:

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

Why?

Is it because the article extended the class without using <String>? Like this:

public class MyArrayAdapter extends ArrayAdapter<String> {

Also, since I'm overriding the class, why do I need to call the original constructor using super?

Pablo Olavo
  • 63
  • 1
  • 5

2 Answers2

0

I think you misunderstand some basic concepts. First, ArrayAdapter required 3 constructor parameter, your class that inherits from it can have as many as you like. Also, you pass the resource id of the list item to it, not the one from the parent.

The basic idea of ArrayAdapter is like this:

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() will return an instance of the layout that you pass to the constructor.

Secondly: The adapter is attached to a ListView. The ListView knows the layout of the view that contains the list and therefore the parent View of each row. The ListView is also the one that calls getView() on the adapter. Just add a break point in getView and you can see who is calling it.

SimonSays
  • 10,867
  • 7
  • 44
  • 59
0

In progress,,

Even though you create a MyArrayAdapterobject, it will not execute any method in this class until you set this one as adapter on your ListView reference. So this ViewGroup parent is coming form the ListView reference to inflate the elements according to the parent parameters accordingly (Parent will be the listview).

If you are going for a completely different custom layout for your each element in the ListView, You do not want to have a resource id passed to your Adapter.

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

        this.values = values;
    }

Because now you are using your custom Layout for your elements and you are inflating then as you like using the following,

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

Now comes the tricky part.

If you actually going to pass the resourceid from your Constructor,

as below,

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

your Custom class is going to me more generic (This has nothing to do with android)

Because,

You can use it here,

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

You should also read this answer to grasp the idea of the ArrayAdapter.

EDIT:

I did not see that coming, Do not miss understand the following

this.parent = resourceid;

with the,

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

parent.

There is do derivation of ViewGroup parent from the passing resourceid (basiclly no relationship) to the super constructor, This ViewGroup parent is coming form the ListView when the ListView reference is set with the adapter.

Community
  • 1
  • 1
diyoda_
  • 5,274
  • 8
  • 57
  • 89