Reputation: 8945
I have inner classes ViewHolder
and StringHolder
in my custon adapter class
private class StringHolder {
String awards; String countries; String directors; String fullPlot; String genres; String ID;
String imdbRating; String imdbVotes; String lastUpdated; String languages; String metacritic;
String posterUrl; String shortPlot; String rating; String releaseDate; String runtime; String writers;
String title; String imdbId; String cast;
public StringHolder(Cursor cursor){
awards = cursor.getString(cursor.getColumnIndexOrThrow("Awards"));
countries = cursor.getString(cursor.getColumnIndexOrThrow("Country"));
directors = cursor.getString(cursor.getColumnIndexOrThrow("Director"));
fullPlot = cursor.getString(cursor.getColumnIndexOrThrow("FullPlot"));
genres = cursor.getString(cursor.getColumnIndexOrThrow("Genre"));
ID = cursor.getString(cursor.getColumnIndexOrThrow("ID"));
imdbRating = cursor.getString(cursor.getColumnIndexOrThrow("imdbRating"));
imdbVotes = cursor.getString(cursor.getColumnIndexOrThrow("imdbVotes"));
lastUpdated = cursor.getString(cursor.getColumnIndexOrThrow("lastUpdated"));
languages = cursor.getString(cursor.getColumnIndexOrThrow("Language"));
metacritic = cursor.getString(cursor.getColumnIndexOrThrow("Metacritic"));
posterUrl = cursor.getString(cursor.getColumnIndexOrThrow("Poster"));
shortPlot = cursor.getString(cursor.getColumnIndexOrThrow("Plot"));
rating = cursor.getString(cursor.getColumnIndexOrThrow("Rating"));
releaseDate = cursor.getString(cursor.getColumnIndexOrThrow("Released"));
runtime = cursor.getString(cursor.getColumnIndexOrThrow("Runtime"));
writers = cursor.getString(cursor.getColumnIndexOrThrow("Writer"));
title = cursor.getString(cursor.getColumnIndexOrThrow("Title"));
imdbId = cursor.getString(cursor.getColumnIndexOrThrow("imdbID"));
cast = cursor.getString(cursor.getColumnIndexOrThrow("Actors"));
}
}
private class ViewHolder {
TextView cast; TextView title; TextView plot; TextView imdbratings; TextView votes;
ImageView bookmark; ImageView share; ImageView IMDBProfile; FlowLayout flowLayout;
TextView releaseDate; TextView directors; TextView countries; TextView genres;
public ViewHolder(View view){
genres = (TextView) view.findViewById(R.id.genres);
countries = (TextView) view.findViewById(R.id.countries);
directors = (TextView) view.findViewById(R.id.directors);
releaseDate = (TextView) view.findViewById(R.id.releaseDate);
title = (TextView) view.findViewById(R.id.Title);
plot = (TextView) view.findViewById(R.id.plot);
imdbratings = (TextView) view.findViewById(R.id.rating);
votes = (TextView) view.findViewById(R.id.votes);
flowLayout = (FlowLayout) view.findViewById(R.id.hash_tag_layout);
bookmark = (ImageView)view.findViewById(R.id.bookmark);
share = (ImageView)view.findViewById(R.id.share);
IMDBProfile = (ImageView)view.findViewById(R.id.IMDBProfile);
cast = (TextView) view.findViewById(R.id.cast);
}
}
I set the strings from StringHolder
(queried from my database) to the text views in ViewHolder
in the bindView
method of my cusotm adapter
public void bindView(final View view, final Context context, final Cursor cursor) {
// Get recycled viewHolder
final ViewHolder viewHolder = (ViewHolder) view.getTag();
// Bind strings to views in viewHolder
StringHolder stringHolder = new StringHolder(cursor);
viewHolder.title.setText(stringHolder.title);
viewHolder.plot.setText(parsePlot(stringHolder.shortPlot, stringHolder.fullPlot));
viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
viewHolder.countries.setText(stringHolder.countries);
viewHolder.directors.setText(stringHolder.directors);
viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
viewHolder.genres.setText(stringHolder.genres);
viewHolder.cast.setText(stringHolder.cast);
}
The problem is my main thread is doing a huge amound of work and skipping frames. I tried binding the views in a new thread like so
public void bindView(final View view, final Context context, final Cursor cursor) {
// Get recycled viewHolder
final ViewHolder viewHolder = (ViewHolder) view.getTag();
// Bind strings to views in viewHolder
new Thread() {
@Override
public void run() {
StringHolder stringHolder = new StringHolder(cursor);
viewHolder.title.setText(stringHolder.title);
viewHolder.plot.setText(parsePlot(stringHolder.shortPlot, stringHolder.fullPlot));
viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
viewHolder.countries.setText(stringHolder.countries);
viewHolder.directors.setText(stringHolder.directors);
viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
viewHolder.genres.setText(stringHolder.genres);
viewHolder.cast.setText(stringHolder.cast);
}
}.start();
}
Now I get this error
Only the original thread that created a view hierarchy can touch its views.
Any idea how to fix the error while maintaing the extra work in a seperate thread?
edit:
Here is my newView
method
// Apply recycling to a view container
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
return view;
}
Upvotes: 0
Views: 915
Reputation: 1428
Its not good idea to move the whole view binding on different thread. seting text to view is not expensive operation creating the StringHolder is. You can AsyncTask to read form the cursor in the doInBackground method, then onPostExecute, which is run on UI thread, you can set values to your views
Upvotes: 1
Reputation: 445
use runOnUiThread()
runOnUiThread(new Runnable() {
@Override
public void run() {
StringHolder stringHolder = new StringHolder(cursor);
viewHolder.title.setText(stringHolder.title);
viewHolder.plot.setText(parsePlot(stringHolder.shortPlot,stringHolder.fullPlot));
viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
viewHolder.countries.setText(stringHolder.countries);
viewHolder.directors.setText(stringHolder.directors);
viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
viewHolder.genres.setText(stringHolder.genres);
viewHolder.cast.setText(stringHolder.cast);
}
});
Upvotes: 0