Load bitmaps in background in chat in order to make UI smoother
This commit is contained in:
parent
28a6f800a5
commit
617beb7db6
2 changed files with 128 additions and 37 deletions
|
@ -283,7 +283,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
topBar.setVisibility(View.GONE);
|
||||
}
|
||||
contactPicture.setVisibility(View.GONE);
|
||||
scrollToEnd();
|
||||
//scrollToEnd();
|
||||
}
|
||||
|
||||
public void hideKeyboardVisibleMode() {
|
||||
|
@ -292,7 +292,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
if (isOrientationLandscape && topBar != null) {
|
||||
topBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
scrollToEnd();
|
||||
//scrollToEnd();
|
||||
}
|
||||
|
||||
class ChatMessageAdapter extends BaseAdapter {
|
||||
|
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
|
@ -33,9 +34,13 @@ import org.linphone.mediastream.Log;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
|
@ -95,7 +100,8 @@ public class BubbleChat {
|
|||
private ImageView statusView;
|
||||
private LinphoneChatMessage nativeMessage;
|
||||
private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener;
|
||||
private static final int SIZE_MAX = 2048;
|
||||
private Context mContext;
|
||||
private static final int SIZE_MAX = 512;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) {
|
||||
|
@ -104,6 +110,7 @@ public class BubbleChat {
|
|||
}
|
||||
nativeMessage = message;
|
||||
fileTransferListener = listener;
|
||||
mContext = context;
|
||||
|
||||
view = new RelativeLayout(context);
|
||||
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
|
@ -160,40 +167,7 @@ public class BubbleChat {
|
|||
});
|
||||
} else {
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
|
||||
Bitmap bm = null;
|
||||
if (appData.startsWith("content")) {
|
||||
try {
|
||||
bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(appData));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(e);
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
} else {
|
||||
bm = BitmapFactory.decodeFile(appData);
|
||||
appData = "file://" + appData;
|
||||
}
|
||||
|
||||
if (bm != null) {
|
||||
if (bm.getWidth() > bm.getHeight() && bm.getWidth() > SIZE_MAX) {
|
||||
bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
|
||||
} else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > SIZE_MAX) {
|
||||
|
||||
bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
|
||||
}
|
||||
|
||||
imageView.setImageBitmap(bm);
|
||||
imageView.setTag(appData);
|
||||
imageView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse((String)v.getTag()), "image/*");
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
loadBitmap(appData, imageView);
|
||||
}
|
||||
} else {
|
||||
TextView msgView = (TextView) layout.findViewById(R.id.message);
|
||||
|
@ -340,4 +314,121 @@ public class BubbleChat {
|
|||
public int getId() {
|
||||
return nativeMessage.getStorageId();
|
||||
}
|
||||
|
||||
public void loadBitmap(String path, ImageView imageView) {
|
||||
if (cancelPotentialWork(path, imageView)) {
|
||||
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
||||
Bitmap defaultBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_photo_default);
|
||||
final AsyncBitmap asyncBitmap = new AsyncBitmap(mContext.getResources(), defaultBitmap, task);
|
||||
imageView.setImageDrawable(asyncBitmap);
|
||||
task.execute(path);
|
||||
}
|
||||
}
|
||||
|
||||
private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
public String path;
|
||||
|
||||
public BitmapWorkerTask(ImageView imageView) {
|
||||
path = null;
|
||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
||||
imageViewReference = new WeakReference<ImageView>(imageView);
|
||||
}
|
||||
|
||||
// Decode image in background.
|
||||
@Override
|
||||
protected Bitmap doInBackground(String... params) {
|
||||
path = params[0];
|
||||
Bitmap bm = null;
|
||||
|
||||
if (path.startsWith("content")) {
|
||||
try {
|
||||
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), Uri.parse(path));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(e);
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
} else {
|
||||
bm = BitmapFactory.decodeFile(path);
|
||||
path = "file://" + path;
|
||||
}
|
||||
|
||||
if (bm != null) {
|
||||
if (bm.getWidth() >= bm.getHeight() && bm.getWidth() > SIZE_MAX) {
|
||||
bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
|
||||
} else if (bm.getHeight() >= bm.getWidth() && bm.getHeight() > SIZE_MAX) {
|
||||
bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
|
||||
}
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
|
||||
// Once complete, see if ImageView is still around and set bitmap.
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap bitmap) {
|
||||
if (isCancelled()) {
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
if (imageViewReference != null && bitmap != null) {
|
||||
final ImageView imageView = imageViewReference.get();
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
if (this == bitmapWorkerTask && imageView != null) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
imageView.setTag(path);
|
||||
imageView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse((String)v.getTag()), "image/*");
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class AsyncBitmap extends BitmapDrawable {
|
||||
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||
|
||||
public AsyncBitmap(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||
super(res, bitmap);
|
||||
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
|
||||
}
|
||||
|
||||
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||
return bitmapWorkerTaskReference.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean cancelPotentialWork(String path, ImageView imageView) {
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
|
||||
if (bitmapWorkerTask != null) {
|
||||
final String bitmapData = bitmapWorkerTask.path;
|
||||
// If bitmapData is not yet set or it differs from the new data
|
||||
if (bitmapData == null || bitmapData != path) {
|
||||
// Cancel previous task
|
||||
bitmapWorkerTask.cancel(true);
|
||||
} else {
|
||||
// The same work is already in progress
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// No task associated with the ImageView, or an existing task was cancelled
|
||||
return true;
|
||||
}
|
||||
|
||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||
if (imageView != null) {
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AsyncBitmap) {
|
||||
final AsyncBitmap asyncDrawable = (AsyncBitmap) drawable;
|
||||
return asyncDrawable.getBitmapWorkerTask();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue