Odhran
Odhran

Reputation: 95

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 :)

Upvotes: 0

Views: 2092

Answers (5)

SAndroidD
SAndroidD

Reputation: 1755

check this link http://www.javacodegeeks.com/2012/06/android-smooth-list-scrolling.html

and also add this in Activity OnCreate() method

protected void onCreate(Bundle savedInstanceState) {

    //StrictMode for smooth list scroll
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    /*----- 
        ListView 
        Custom Adapter set data....
    ------*/

}

Upvotes: 0

evertvandenbruel
evertvandenbruel

Reputation: 1193

I had the same problem today and while using the viewHolder pattern the scrolling was still laggy, until I wanted to show the problem to a colleague and noticed that scrolling was smooth. So the problem in my case was that I was connected to the debugger and that slowed things down.

Upvotes: 1

Adil Soomro
Adil Soomro

Reputation: 37729

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!

Upvotes: 5

ramdroid
ramdroid

Reputation: 6798

What are you doing in films.get(position)?

If you are reading from a database then your scrolling might really be bad here...

When using a database you should load the data into the adapter during onCreate, probably something like that (but with your previous listview layout etc.)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    List<FilmRecord> values = films.getAllFilms();


    ArrayAdapter<FilmRecord> adapter = new ArrayAdapter<FilmRecord>(this,
                your_list_item_layout_id, values);
    your_list_view.setListAdapter(adapter);
}

In the getView() method you just have to ask the adapter:

FilmRecord film = getItem(position);

Upvotes: 0

Hiral Vadodaria
Hiral Vadodaria

Reputation: 19250

Please refer this question and see my answer there.It shows how you should declare your components in your custom adapter class.Making these changes to your class will definitely solve your problem as the question i suggested here also had the similar issue as yours:Scrolable ListView with costumized BaseAdapter is very slow

Upvotes: 0

Related Questions