Search code examples
androidlistviewcustom-lists

Custom listview scrollin isn't smooth


I've created a custom listview which is working great apart from the fact that the list doesn't smooth scroll. Its choppy and slow.

Here's the code where I populate the listview:

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listitem, null);
        }

        FilmRecord film = films.get(position);
        if (film != null) {
            TextView filmTitle = (TextView) v.findViewById(R.id.filmtitle);
            TextView filmShowingDate = (TextView) v.findViewById(R.id.filmshowingtime);
            TextView filmAdded = (TextView) v.findViewById(R.id.filmadded);
            TextView filmLocations = (TextView) v.findViewById(R.id.filmlocations);
            TextView filmDescription = (TextView) v.findViewById(R.id.filmdescription);
            TextView filmProvider = (TextView) v.findViewById(R.id.filmprovider);
            TextView filmTicketUrl = (TextView) v.findViewById(R.id.filmticketurl);


            if (filmTitle != null) {
                filmTitle.setText(film.filmTitle);
            }

            if(filmDescription != null) {
                filmDescription.setText(film.filmDescription );
            }

            if(filmLocations != null) {
                filmLocations.setText(film.filmLocations );
            }

            if(filmShowingDate != null) {
                filmShowingDate.setText("Showing: " + film.filmShowingDate );
            }

            if(filmAdded != null) {
                filmAdded.setText("Added on: " + film.filmAdded );
            }

            if(filmProvider != null) {
                filmProvider.setText(film.filmProvider );
            }

            if(filmTicketUrl != null) {
                filmTicketUrl.setText(film.filmTicketUrl );
            }
        }

        //Check who the provider is and set the imageview to provider logo
        ImageView imageView = (ImageView) v.findViewById(R.id.providerImage);
        if(film.filmProvider.equals("Cineworld")) {
            Log.d("Provider", "Provider is Cineworld");
            imageView.setImageResource(R.drawable.cineworld);
        }
        else if(film.filmProvider.equals("Show Film Fist")){
            Log.d("Provider", "Provider is Show Film Fist");
            imageView.setImageResource(R.drawable.show_film_first);
        }

        return v;
    }

Has anyone had similar issues when creating a custom listview? Any help as always would be much appreciated :)


Solution

  • You need to use ViewHolder approach.

    because finding the View by id also takes time to execute.

    by using ViewHolder approach you will be able to minimize the load created during finding View by id by caching the views :)

    Here is nice tutorial how to do that.

    Edit:

    What ViewHolder approach do is:

    Say you have 4 visible items in your ListView at a time. You have to inflate the View 4 time and findViewById() 4 times only even if you scroll to 1000th item in ListView.

    But if you don't use ViewHolder and you have put

    if (v == null) {
       LayoutInflater vi = ...;
    }else{
       //... other implementation 
    }
    

    You have to inflate the View 4 time only, but findViewById() will be called every time when the getView() is called (usually when ListView is scrolled).

    Happy coding!