image view performance improvement
This commit is contained in:
parent
117c89b81d
commit
2df5ddad6c
|
@ -26,6 +26,7 @@ import org.nuclearfog.twidda.adapter.ImageAdapter.OnImageClickListener;
|
|||
import org.nuclearfog.twidda.backend.ImageLoader;
|
||||
import org.nuclearfog.twidda.backend.engine.EngineException;
|
||||
import org.nuclearfog.twidda.backend.helper.ErrorHandler;
|
||||
import org.nuclearfog.twidda.backend.holder.ImageHolder;
|
||||
import org.nuclearfog.zoomview.ZoomView;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -143,7 +144,8 @@ public class MediaViewer extends AppCompatActivity implements OnImageClickListen
|
|||
|
||||
@Override
|
||||
public void onImageClick(Bitmap image) {
|
||||
changeImage(image);
|
||||
zoomImage.reset();
|
||||
zoomImage.setImageBitmap(image);
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,27 +203,16 @@ public class MediaViewer extends AppCompatActivity implements OnImageClickListen
|
|||
}
|
||||
|
||||
|
||||
public void setImage(Bitmap image) {
|
||||
public void setImage(ImageHolder image) {
|
||||
if (adapter.isEmpty()) {
|
||||
changeImage(image);
|
||||
zoomImage.reset();
|
||||
zoomImage.setImageBitmap(image.getMiddleSize());
|
||||
image_progress.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
adapter.addLast(image);
|
||||
}
|
||||
|
||||
|
||||
private void changeImage(Bitmap image) {
|
||||
int width = zoomImage.getMeasuredWidth();
|
||||
if (width > 0 && image.getWidth() > width) {
|
||||
float ratio = image.getWidth() / (float) width;
|
||||
int destHeight = (int) (image.getHeight() / ratio);
|
||||
image = Bitmap.createScaledBitmap(image, width, destHeight, false);
|
||||
}
|
||||
zoomImage.reset();
|
||||
zoomImage.setImageBitmap(image);
|
||||
}
|
||||
|
||||
|
||||
private void storeImage(Bitmap image) {
|
||||
String name = "shitter_" + formatter.format(new Date());
|
||||
try {
|
||||
|
|
|
@ -12,21 +12,24 @@ import androidx.annotation.NonNull;
|
|||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
import org.nuclearfog.twidda.backend.holder.ImageHolder;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.widget.ListPopupWindow.MATCH_PARENT;
|
||||
import static android.widget.ListPopupWindow.WRAP_CONTENT;
|
||||
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
|
||||
|
||||
|
||||
public class ImageAdapter extends Adapter<ImageAdapter.ImageHolder> {
|
||||
public class ImageAdapter extends Adapter<ViewHolder> {
|
||||
|
||||
private static final int PICTURE = 0;
|
||||
private static final int LOADING = 1;
|
||||
|
||||
private OnImageClickListener itemClickListener;
|
||||
|
||||
private List<Bitmap> images;
|
||||
private List<ImageHolder> images;
|
||||
private boolean loading;
|
||||
|
||||
|
||||
|
@ -38,11 +41,11 @@ public class ImageAdapter extends Adapter<ImageAdapter.ImageHolder> {
|
|||
|
||||
|
||||
@MainThread
|
||||
public void addLast(@NonNull Bitmap image) {
|
||||
public void addLast(@NonNull ImageHolder imageItem) {
|
||||
int imagePos = images.size();
|
||||
if (imagePos == 0)
|
||||
loading = true;
|
||||
images.add(image);
|
||||
images.add(imageItem);
|
||||
notifyItemInserted(imagePos);
|
||||
}
|
||||
|
||||
|
@ -78,56 +81,73 @@ public class ImageAdapter extends Adapter<ImageAdapter.ImageHolder> {
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public ImageAdapter.ImageHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
|
||||
if (viewType == LOADING) {
|
||||
public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
|
||||
if (viewType == PICTURE) {
|
||||
ImageView preview = new ImageView(parent.getContext());
|
||||
preview.setBackgroundColor(0xffffffff);
|
||||
preview.setPadding(1, 1, 1, 1);
|
||||
final ImageItem item = new ImageItem(preview);
|
||||
preview.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int pos = item.getAdapterPosition();
|
||||
if (pos != NO_POSITION) {
|
||||
Bitmap img = images.get(pos).getMiddleSize();
|
||||
itemClickListener.onImageClick(img);
|
||||
}
|
||||
}
|
||||
});
|
||||
preview.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
int pos = item.getAdapterPosition();
|
||||
if (pos != NO_POSITION) {
|
||||
Bitmap img = images.get(pos).getOriginalImage();
|
||||
itemClickListener.onImageTouch(img);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return item;
|
||||
} else {
|
||||
ProgressBar circle = new ProgressBar(parent.getContext());
|
||||
LayoutParams param = new LayoutParams(WRAP_CONTENT, MATCH_PARENT);
|
||||
circle.setLayoutParams(param);
|
||||
return new ImageHolder(circle);
|
||||
} else {
|
||||
return new ImageHolder(new ImageView(parent.getContext()));
|
||||
return new LoadItem(circle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ImageAdapter.ImageHolder vh, int index) {
|
||||
if (vh.view instanceof ImageView) {
|
||||
final Bitmap image = images.get(index);
|
||||
ImageView imageView = (ImageView) vh.view;
|
||||
imageView.setImageBitmap(downscale(image));
|
||||
imageView.setBackgroundColor(0xffffffff);
|
||||
imageView.setPadding(1, 1, 1, 1);
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
itemClickListener.onImageClick(image);
|
||||
}
|
||||
});
|
||||
imageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
itemClickListener.onImageTouch(image);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
public void onBindViewHolder(@NonNull ViewHolder vh, int index) {
|
||||
if (vh instanceof ImageItem) {
|
||||
ImageItem item = (ImageItem) vh;
|
||||
Bitmap image = images.get(index).getSmallSize();
|
||||
item.preview.setImageBitmap(image);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder for image
|
||||
*/
|
||||
class ImageItem extends ViewHolder {
|
||||
final ImageView preview;
|
||||
|
||||
private Bitmap downscale(Bitmap image) {
|
||||
float ratio = image.getHeight() / 256.0f;
|
||||
int destWidth = (int) (image.getWidth() / ratio);
|
||||
return Bitmap.createScaledBitmap(image, destWidth, 256, false);
|
||||
ImageItem(ImageView preview) {
|
||||
super(preview);
|
||||
this.preview = preview;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder for progress circle
|
||||
*/
|
||||
class LoadItem extends ViewHolder {
|
||||
final ProgressBar circle;
|
||||
|
||||
static class ImageHolder extends ViewHolder {
|
||||
final View view;
|
||||
|
||||
ImageHolder(View view) {
|
||||
super(view);
|
||||
this.view = view;
|
||||
LoadItem(ProgressBar circle) {
|
||||
super(circle);
|
||||
this.circle = circle;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.nuclearfog.twidda.backend;
|
|||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Point;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -10,6 +11,7 @@ import androidx.annotation.Nullable;
|
|||
import org.nuclearfog.twidda.activity.MediaViewer;
|
||||
import org.nuclearfog.twidda.backend.engine.EngineException;
|
||||
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
|
||||
import org.nuclearfog.twidda.backend.holder.ImageHolder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
|
@ -18,12 +20,15 @@ import java.lang.ref.WeakReference;
|
|||
*
|
||||
* @see MediaViewer
|
||||
*/
|
||||
public class ImageLoader extends AsyncTask<String, Bitmap, Boolean> {
|
||||
public class ImageLoader extends AsyncTask<String, ImageHolder, Boolean> {
|
||||
|
||||
private static final float PREV_HEIGHT_RATIO = 5.0f;
|
||||
|
||||
@Nullable
|
||||
private EngineException err;
|
||||
private WeakReference<MediaViewer> callback;
|
||||
private TwitterEngine mTwitter;
|
||||
private WeakReference<MediaViewer> callback;
|
||||
private float previewHeight, zoomPreview;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -34,6 +39,10 @@ public class ImageLoader extends AsyncTask<String, Bitmap, Boolean> {
|
|||
public ImageLoader(@NonNull MediaViewer callback) {
|
||||
this.callback = new WeakReference<>(callback);
|
||||
mTwitter = TwitterEngine.getInstance(callback);
|
||||
Point displaySize = new Point();
|
||||
callback.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
||||
zoomPreview = displaySize.x;
|
||||
previewHeight = displaySize.y / PREV_HEIGHT_RATIO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +57,8 @@ public class ImageLoader extends AsyncTask<String, Bitmap, Boolean> {
|
|||
image = BitmapFactory.decodeFile(link);
|
||||
}
|
||||
if (image != null) {
|
||||
publishProgress(image);
|
||||
ImageHolder images = new ImageHolder(image, previewHeight, zoomPreview);
|
||||
publishProgress(images);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -62,9 +72,10 @@ public class ImageLoader extends AsyncTask<String, Bitmap, Boolean> {
|
|||
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Bitmap[] btm) {
|
||||
if (callback.get() != null)
|
||||
callback.get().setImage(btm[0]);
|
||||
protected void onProgressUpdate(ImageHolder[] images) {
|
||||
if (callback.get() != null) {
|
||||
callback.get().setImage(images[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package org.nuclearfog.twidda.backend.holder;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Container class for Bitmap images and previews
|
||||
*/
|
||||
public class ImageHolder {
|
||||
|
||||
private Bitmap smallImage, middleImage, fullImage;
|
||||
|
||||
|
||||
public ImageHolder(@NonNull Bitmap fullImage, float smallImageHeight, float middleImageWidth) {
|
||||
this.fullImage = fullImage;
|
||||
|
||||
float ratio = fullImage.getHeight() / smallImageHeight;
|
||||
int destWidth = (int) (fullImage.getWidth() / ratio);
|
||||
smallImage = Bitmap.createScaledBitmap(fullImage, destWidth, (int) smallImageHeight, false);
|
||||
|
||||
if (middleImageWidth > 0 && fullImage.getWidth() > middleImageWidth) {
|
||||
ratio = fullImage.getWidth() / middleImageWidth;
|
||||
int destHeight = (int) (fullImage.getHeight() / ratio);
|
||||
middleImage = Bitmap.createScaledBitmap(fullImage, (int) middleImageWidth, destHeight, false);
|
||||
} else {
|
||||
middleImage = fullImage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get small sized image
|
||||
*
|
||||
* @return Image Bitmap
|
||||
*/
|
||||
public Bitmap getSmallSize() {
|
||||
return smallImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* get Middle sized image
|
||||
*
|
||||
* @return Image Bitmap
|
||||
*/
|
||||
public Bitmap getMiddleSize() {
|
||||
return middleImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* get Original Image
|
||||
*
|
||||
* @return Image Bitmap
|
||||
*/
|
||||
public Bitmap getOriginalImage() {
|
||||
return fullImage;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue