Let me explain what I am doing first before I get into everything
basically I give the user an option to choose an image from the SD card, store the Uri of selected image in my database and have that as the avatar for the list item but the more list items with an avatar there are the slower the scrolling of the list is
I load the list with a Loader
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(getActivity(),BowlersDB.CONTENT_URI,
new String[] {BowlersDB.ID,BowlersDB.FIRST_NAME,BowlersDB.LAST_NAME,BowlersDB.PHOTO_URI},null,null,BowlersDB.LAST_NAME + " COLLATE LOCALIZED ASC");
}
I have a custom adapter that adjusts the image size sets the textviews etc.
@Override
public void bindView(final View view,final Context context,final Cursor cursor){
final int id = cursor.getInt(0);;
final QuickContactBadge image = (QuickContactBadge)view.findViewById(R.id.quickContactBadge1);
image.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
if(!fromGame){
bowlerID = id;
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i,1);
}
}
});
String uri = cursor.getString(3);
if(uri != null){
InputStream input=null;
try {
input = getActivity().getContentResolver().openInputStream(Uri.parse(cursor.getString(3)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
Bitmap og = BitmapFactory.decodeStream(input,null,options);
int height = options.outHeight;
int width = options.outWidth;
BitmapFactory.decodeResource(getResources(), R.drawable.ic_contact_picture, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
float scaledHeight = ((float)imageHeight)/height;
float scaledWidth = ((float)imageWidth)/width;
Matrix matrix = new Matrix();
matrix.postScale(scaledWidth, scaledHeight);
final Bitmap resized = Bitmap.createBitmap(og, 0, 0, width, height, matrix, true);
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
image.setImageBitmap(resized);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else{
image.setImageResource(R.drawable.ic_contact_picture);
}
TextView first = (TextView)view.findViewById(R.id.bListTextView);
TextView last = (TextView)view.findViewById(R.id.bListTextView2);
first.setText(cursor.getString(1));
last.setText(cursor.getString(2));
}
}
Now I know its probably the sizing of the image that is causing it to be so slow but when I put that section of code in a separate thread and that had no effect but I thought a LoaderManager loads everything in the background anyway
here is my row xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="60dp"
android:id="@+id/names_layout"
android:background="@drawable/list_item_state">
<QuickContactBadge
android:id="@+id/quickContactBadge1"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="@drawable/ic_contact_picture"
style="?android:attr/quickContactBadgeStyleWindowLarge" />
<TextView
android:id="@+id/bListTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/quickContactBadge1"
android:background="@drawable/list_item_state"
android:paddingLeft="20dp"
android:paddingTop="2dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="20dp"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:id="@+id/bListTextView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/quickContactBadge1"
android:layout_below="@+id/bListTextView"
android:paddingLeft="20dp"
android:background="@drawable/list_item_state"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="15dp"
android:textColor="?android:attr/textColorSecondary"
android:layout_alignBottom="@+id/quickContactBadge1"/>
</RelativeLayout>
the Quick Contact Badge holds the image and I have a default image set for if there is no image set.
So how can I fix this?
An example of what I am trying to do would be the google music app where the album list has all those album avatars and there is no problem scrolling, they appear on a as needed basis it seems but obviously its a bit different since the images are probably downloaded from the server
You are streaming the image in the bindView thread, which generally is not a good idea. I usually do downloading and building bitmaps in an asyncTask – or rather, in a RoboAsyncTask. I pass the ImageView along with the image URL, so the image is set after the downloading or bitmapcreation is done, in the onSuccess() of the asynctask. What you see on the screen is images appearing shortly after the other content. You can also pass a placeholder resource to the async task, to display while the downloading is being done.
In your activity or fragment:
in MediaManager:
In SetImageTask (extends RoboAsyncTask):