How Does the Getview() Method Work When Creating Your Own Custom Adapter

How does the getView() method work when creating your own custom adapter?

1: The LayoutInflater takes your layout XML-files and creates different View-objects from its contents.

2: The adapters are built to reuse Views, when a View is scrolled so that is no longer visible, it can be used for one of the new Views appearing. This reused View is the convertView. If this is null it means that there is no recycled View and we have to create a new one, otherwise we should use it to avoid creating a new.

3: The parent is provided so you can inflate your view into that for proper layout parameters.

All these together can be used to effectively create the view that will appear in your list (or other view that takes an adapter):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
if (convertView == null) {
//We must create a View:
convertView = inflater.inflate(R.layout.my_list_item, parent, false);
}
//Here we can do changes to the convertView, such as set a text on a TextView
//or an image on an ImageView.
return convertView;
}

Notice the use of the LayoutInflater, that parent can be used as an argument for it, and how convertView is reused.

How does getView() work in a custom adapter?

How does getView() work in a custom adapter?

getView() method is called as many times as is number of rows e.q. each row has own View.

Now, this 'reuse' is confusing me.

It's called View recycling. In other words, if row is not visible, its not null (if was created and visible at least once) but if you won't create mechanism that will hold child views of row, recycling wont work and in your case your findViewById() will be called for each row (in the case of for example 1000 rows, its not very efficient).

For this purpose is used Holder design-pattern. It's simple arbitrary object that holds references of child views of each row.

You can implement it like:

public class RowHolder {

private View row;

// childs widgets in row
private TextView name;

public RowHolder(View row) {
this.row = row; // row in ListView (in your case)
}

public TextView getName() {
if (name == null) {
name = (TextView) row.findViewById(<id>);
}
return name;
}

...
}

And a usage:

LayoutInflater inflater;
RowHolder holder = null;

// row created first time
if (convertView == null) {
convertView = inflater.inflate(<rowXMLLayout>, null, false);
holder = new RowHolder(convertView); // adding row to arbitrary obj
convertView.setTag(holder) // adding this obj to row at position
}
else {
// recycling started
holder = (RowHolder) convertView.getTag();
}

// updating rows
holder.getName().setText(<value?>);
...

How does ArrayAdapter getView() method works?

getView() is the main part of your adapter. It returns View that will be displayed as your list/grid/gallary/any view that use adapter item. It triggers when you scroll the view(list for example).

So the first thing you should do its to create your custom adapter. You may extend it from BaseAdapter. Then you need to create some data to display (or pass it to adapter from out side - its better solution).

After that override getView() method and make sure to return your custom View there. In your case it should be a Layout with ImageView and TextView (and dont forget to fill them).

You can learn more from :

  • http://www.youtube.com/watch?v=N6YdwzAvwOA
  • http://www.edureka.in/blog/what-are-adapters-in-android/
  • http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

My getView method in my custom array adapter is not working

 if(convertView!=null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent);
}

should be

if(convertView==null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent);
}

you have to inflate when the convertview is null. not when its not null. And then return this from your getView() method

Also i can not see getCount() method. It is also very important to tell the adapter about how many items to inflate

Custom adapter getview is not called

It's because getCount() returns zero.
The number you return in getCount() is the times the getView() will be called.
In getCount() you should always return the size of the list.

Therefore

@Override
public int getCount() {
return list.size();
}

@Override
public ModuleItem getItem(int position) {
return list.get(position);
}

Also, maybe the layout's ListView id is not android.R.id.list?

Make sure you have in xml

<ListView
android:id="@android:id/list"
...

Also, don't ever pass any data to a fragment in constructor.

WRONG:

public ModuleItemListFragment(List<ModuleItem> list,Module mod) {
super();
this.list=list;
this.mod=mod;
}

RIGHT:

private static final String EXTRA_LIST = "ModuleItemListFragment.EXTRA_LIST";
private static final String EXTRA_MODULE = "ModuleItemListFragment.EXTRA_MODULE";

public static ModuleItemListFragment instantiate(ArrayList<ModuleItem> list, Module mod) {
final Bundle args = new Bundle();
args.putParcelable(EXTRA_LIST, list);
args.putParcelable(EXTRA_MODULE, module);

final ModuleItemListFragment f = new ModuleItemListFragment();
f.setArguments(args);
return f;
}

@Override
public void onCreate(Bundle state) {
super.onCreate(state);
final Bundle args = getArguments();
this.list = args.getParcelable(EXTRA_LIST);
this.module = args.getParcelable(EXTRA_MODULE);
}

Of course, you have to make your Module Parcelable or Serializable.

You must specify args because the Fragment can be killed and restored by the system and if you pass data via setters or constructors they will not be restored and therefore can become null in some circumstances.

Custom Adapter getView() method is not called

The only reasons getView is not called are:

  1. getCount returns 0.
  2. you forget to call setAdapter on the ListView.
  3. If the ListView's visibility (or its container's visibility) is GONE. Thanks to @TaynãBonaldo for the valuable input.
  4. ListView is not attached to any viewport layout. That is, mListView = new ListView(...) is used without myLayout.addView(mListView).

In the onPostExcute, after you create a new instance of CarListAdapter I will suggest you to update the new instance to your ListView. Indeed you need to call again

 mList.setAdapter(adapter);

Edit: setAdapter should be always called on the ui thread, to avoid unexpected behaviours

Edit2:

The same applies to RecyclerView. Make sure that

  • getItemCount is returning a value grater than 0 (usually the dataset size)
  • both setLayoutManager and setAdapter have to be called on the UI Thread
  • The visibility of the widget has to be set to VISIBLE

How Android Custom Adapter works?

I think this link can help you. getview is a callback function which will be called automatically when you will display your listview on Activity. When you display your listview then you overrides getview and inflates your row from XML or dynamically creates your row. That row you return as a view which displays in your listview.

How does the getView() method work when creating your own custom adapter?

For each row getview will be called once. You create your layouts and return them as view. Those respective views displays in your lisview rows.



Related Topics



Leave a reply



Submit