Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android listview viewholder. when to use it, and when not to

I have a ListView with a custom list adapter. In the getView() method, am using the ViewHolder 'pattern' as shown in the API Demos for ListView14.java. When i first render the list it seems to load correctly. However, the issue i'm running into is that when i scroll the list, i'm seeing the data for the list show up in the wrong rows (i.e. a TextView that should be in row 10 is showing up in row 2 for example). However, when I do not use the viewholder, and instead call findViewById() every time, then the list view renders correctly.

like image 828
Ben Avatar asked Jul 08 '10 23:07

Ben


People also ask

What is the ViewHolder pattern Why should we use it?

The ViewHolder design pattern enables you to access each list item view without the need for the look up, saving valuable processor cycles. Specifically, it avoids frequent call of findViewById() during ListView scrolling, and that will make it smooth.

What is the benefit of ViewHolder pattern in Android?

ViewHolder design pattern is used to speed up rendering of your ListView - actually to make it work smoothly. Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance.

What is the use of ViewHolder?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive findViewById results.

What is the main advantage of reusing views in getView () of an adapter?

Advantage is that if you properly reuse RECYCLED VIEW in your getView, then command inflate() will be invoked sometimes only once (but not for every list item, when it's not necessary ).


2 Answers

However, the issue i'm running into is that when i scroll the list, i'm seeing the data for the list show up in the wrong rows (i.e. a TextView that should be in row 10 is showing up in row 2 for example).

Most likely, you are improperly recycling your rows, such that the ViewHolders you are manipulating are not the right ones for the row you are returning.

Here is a free excerpt from one of my books that goes into more about row recycling -- perhaps it will help you identify where things are going wrong.

like image 50
CommonsWare Avatar answered Sep 23 '22 02:09

CommonsWare


  • I faced same problem
  • Solved using below techninc
  • Reason : Adapter not Loaded Frequentlyy.
  • in Your Custom Adapter class add ViewHolder using Access Specifiers

    private static class ViewHolder {
    
            protected TextView itemName;
    
        }
    

In Get View method

    @Override

        public View getView(int position, View view, ViewGroup viewGroup) {

            // create a ViewHolder reference
            ViewHolder holder;

            //check to see if the reused view is null or not, if is not null then reuse it
            if (view == null) {
                holder = new ViewHolder();

                view = mLayoutInflater.inflate(R.layout.list_item, null);
                holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);

                // the setTag is used to store the data within this view
                view.setTag(holder);
            } else {
                // the getTag returns the viewHolder object set as a tag to the view
                holder = (ViewHolder)view.getTag();
            }
    // now Use Holder object toget Idss 

    holder.itemName.setText(" sample text based on position ");
    }

Important : And We should not set Any Tag for view object except Viewholder Object

like image 45
sravan Avatar answered Sep 26 '22 02:09

sravan