问题
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 :)
回答1:
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!
回答2:
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.
回答3:
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
回答4:
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);
回答5:
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....
------*/
}
来源:https://stackoverflow.com/questions/9359047/custom-listview-scrollin-isnt-smooth