Reputation: 1057
Edit: Ok, i took the advice given in the answers and the difference is huge! I've replaced my SeriesAdapter in the post with the new one. For one a know make the calculations with in the sql query (to know total number of episodes and totalt numer of watched episodes). I also store the bitmap in a hashmap once it has been loaded so that it don't have to load twice, I'm looking in to some other solution as I'm afraid of OutOfMemoryException.
I am new to android and i want to display an listview with images that i have stored on the external storage.
The images are downloaded earlier and are now as I said stored in the external storage, here is an example of the images http://thetvdb.com/banners/graphical/80348-g32.jpg and I compress the images to 80% when saving them to save some space.
I have tried several methods to make the listview scroll smooth but I'm clearly in over my head here. I have provided my layout for the list items and my adapter in case I do something strange here.
I would appreciate any tips and tricks that would improve my listview.
SeriesAdapter:
public static class SeriesAdapter extends ArrayAdapter<Series> {
static class viewHolder
{
ImageView image;
TextView information;
String seriesId;
String season;
ProgressBar progress;
TextView txtSmallView;
}
private final Context context;
private final ArrayList<Series> series;
private DateHelper dateHelper;
private final DatabaseHandler db;
Object mActionMode;
int resource;
public SeriesAdapter(Context context, int resource, ListView lv, ArrayList<ExtendedSeries> objects)
{
super(context, resource, objects);
this.context = context;
this.series = objects;
this.resource = resource;
db = new DatabaseHandler(context);
dateHelper = new DateHelper();
cache = new HashMap<String, Bitmap>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
viewHolder holder;
ExtendedSeries s = series.get(position);
if(convertView == null)
{
convertView = View.inflate(context, resource, null);
holder = new viewHolder();
holder.image = (ImageView)convertView.findViewById(R.id.imgSeriesImage);
holder.information = (TextView)convertView.findViewById(R.id.txtUpcomingEpisode);
holder.progress = (ProgressBar)convertView.findViewById(R.id.pgrWatched);
convertView.setTag(holder);
}
else
{
holder = (viewHolder)convertView.getTag();
}
if(s != null)
{
holder.seriesId = s.getImage();
convertView.setTag(R.string.homeactivity_tag_id,s.getID());
convertView.setTag(R.string.homeactivity_tag_seriesid,s.getSeriesId());
holder.progress.setMax(s.getTotalEpisodes());
holder.progress.setProgress(s.getWatchedEpisodes());
holder.image.setImageBitmap(getBitmapFromCache(s.getImage()));
holder.information.setText(s.getNextEpisodeInformation().equals("") ? context.getText(R.string.message_show_ended) : s.getNextEpisodeInformation());
}
return convertView;
}
Listitem layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/imgSeriesImage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:focusable="false"
android:scaleType="centerCrop"
android:src="@drawable/noimage" />
<RelativeLayout
android:id="@+id/relProgressView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/pgrWatched"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="21dp"
android:max="100"
android:progress="50"
android:progressDrawable="@drawable/progressbar" />
<TextView
android:id="@+id/txtUpcomingEpisode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:padding="3dp"
android:scrollHorizontally="true"
android:scrollbars="none"
android:shadowColor="@android:color/black"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:textAllCaps="true"
android:textColor="#ffffffff"
android:textSize="11sp"
android:textStyle="normal|bold"
android:typeface="normal" />
</RelativeLayout>
Activity layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ListView
android:id="@+id/lstMySeries"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:longClickable="true"
android:divider="#000000"
/>
Upvotes: 2
Views: 2157
Reputation: 13327
I dont know why your code are doing an IO operation in the getView()
method . this is an expensive operation ,can't you make it a field in the DB ??? can't you calcaulated else where ??? perhaps in the data loader i.e where you load the series ,.
Upvotes: 0
Reputation: 46425
The getView
method needs to be as light as possible as this is called for every item in the row when it is shown onscreen.
You already implement the viewHolder
pattern which is good, but you also need to preprocess your "watched episode" logic so you are not looping and counting in the display code. You also need to do the db.GetAiredEpisodes call outside of this method call.
Upvotes: 2