What I'm trying do to is using a custom CursorAdapter, in order to choose which layout to show and also to populate View items such as TextViews and also ImageView.
Now not in all the listview items there gonna be an image.
My CursorAdapter code is -
private static class ViewHolder {
TextView mesg;
TextView mesg2;
TextView send;
ImageView myImage;
}
public class ChatCursorAdapter extends CursorAdapter implements OnClickListener {
public ChatCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
}
@Override
public int getCount() {
return getCursor() == null ? 0 : super.getCount();
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int _position) {
Cursor cursor = (Cursor) getItem(_position);
return getItemViewType(cursor);
}
private int getItemViewType(Cursor cursor) {
String sender = cursor.getString(2);
String saveUser = user;
if (saveUser.equalsIgnoreCase(sender)){
return 0;
}else{
return 1;
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
String msg = cursor.getString(3);
String msg2 = cursor.getString(4);
String sender = cursor.getString(2);
holder.mesg.setText(getSmiledText(Main.this,msg));
holder.mesg2.setText(getSmiledText(Main.this,msg2));
holder.send.setText(sender);
picPath = cursor.getString(8);
if(picPath == null || picPath.isEmpty()){
holder.myImage.setVisibility(View.GONE);
}else{
File file = new File(picPath);
if(file.exists()){
new AsyncImageSetter(holder.myImage, picPath).execute();
holder.myImage.setOnClickListener(this);
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View itemLayout = null;
switch(getItemViewType(cursor)){
case 0:
itemLayout = getLayoutInflater().inflate(R.layout.msg_item1,parent, false);
break;
case 1:
itemLayout = getLayoutInflater().inflate(R.layout.msg_item13, parent,false);
break;
}
itemLayout.setTag(holder);
holder.mesg = (TextView) itemLayout.findViewById(R.id.text_start);
holder.mesg2 = (TextView) itemLayout.findViewById(R.id.text_end);
holder.send = (TextView) itemLayout.findViewById(R.id.text_from);
holder.myImage = (ImageView) itemLayout.findViewById(R.id.imageView_msgpic);
return itemLayout;
}
}
As you can see when there a need to load an image to the ImageView, I'm using asynctask in order to let the flow of the list view scrolling to be much more smoother.
This how the asynctask code is -
public class AsyncImageSetter extends AsyncTask<Void, Void, Void> {
private ImageView img;
private String path;
private Bitmap bm;
public AsyncImageSetter(ImageView img, String path) {
this.img = img;
this.path = path;
}
@Override
protected Void doInBackground(Void... params) {
bm = BitmapFactory.decodeFile(path);
bm = setImageToImageView(path);
return null;
}
@Override
protected void onPostExecute(Void result) {
img.setTag(path);
img.setImageBitmap(bm);
//img.setVisibility(View.VISIBLE);
super.onPostExecute(result);
}
}
Well the thing is that it sure made the scrolling alot more smoother, but it seems to make the app crash a lot of times.
The logcat says the next -
03-24 17:07:34.125: E/AndroidRuntime(15422): FATAL EXCEPTION: AsyncTask #2
03-24 17:07:34.125: E/AndroidRuntime(15422): java.lang.RuntimeException: An error occured while executing doInBackground()
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.os.AsyncTask$3.done(AsyncTask.java:299)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.lang.Thread.run(Thread.java:841)
03-24 17:07:34.125: E/AndroidRuntime(15422): Caused by: java.lang.OutOfMemoryError
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:378)
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417)
03-24 17:07:34.125: E/AndroidRuntime(15422): at at.vcity.androidim.MainChat$AsyncImageSetter.doInBackground(MainChat.java:3356)
03-24 17:07:34.125: E/AndroidRuntime(15422): at at.vcity.androidim.MainChat$AsyncImageSetter.doInBackground(MainChat.java:1)
03-24 17:07:34.125: E/AndroidRuntime(15422): at android.os.AsyncTask$2.call(AsyncTask.java:287)
03-24 17:07:34.125: E/AndroidRuntime(15422): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
03-24 17:07:34.125: E/AndroidRuntime(15422): ... 4 more
So what am I doing wrong here?
Thanks for any kind of help