Add a progressbar to the imageviewer

filtering
Floens 10 years ago
parent 4a948c591f
commit a06f2b9283
  1. 47
      Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java
  2. 10
      Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java
  3. 11
      Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java
  4. 6
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java
  5. 52
      Clover/app/src/main/java/org/floens/chan/ui/view/LoadingBar.java
  6. 43
      Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java
  7. 7
      Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java
  8. 5
      Clover/app/src/main/res/layout/controller_image_viewer.xml

@ -1,12 +1,10 @@
package org.floens.chan.core.presenter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import org.floens.chan.core.model.PostImage;
import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.ui.view.MultiImageView;
import org.floens.chan.utils.Logger;
import java.io.File;
import java.util.ArrayList;
@ -23,6 +21,7 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
private boolean entering = true;
private boolean exiting = false;
private List<PostImage> images;
private List<Float> progress;
private int selectedPosition;
// Disables swiping until the view pager is visible
@ -37,7 +36,10 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
this.images = images;
selectedPosition = position;
Logger.test("showImages position " + position);
progress = new ArrayList<>(images.size());
for (int i = 0; i < images.size(); i++) {
progress.add(i, -1f);
}
// Do this before the view is measured, to avoid it to always loading the first two pages
callback.setPagerItems(images, selectedPosition);
@ -66,12 +68,11 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
callback.setPagerVisiblity(false);
callback.setPreviewVisibility(true);
callback.startPreviewOutTransition(images.get(selectedPosition));
callback.showProgress(false);
}
@Override
public void onPageSelected(int position) {
Logger.test("onPageSelected " + selectedPosition + ", " + position);
if (!viewPagerVisible) {
return;
}
@ -111,7 +112,6 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
onLowResInCenter();
} else {
if (multiImageView.getPostImage() == images.get(selectedPosition)) {
Log.i(TAG, "Loading high res from a onModeLoaded");
onLowResInCenter();
}
}
@ -128,10 +128,12 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
// Already in LOWRES mode
if (callback.getImageMode(images.get(selectedPosition)) == MultiImageView.Mode.LOWRES) {
Log.i(TAG, "Loading high res from a swipe");
onLowResInCenter();
}
// Else let onModeChange handle it
callback.showProgress(progress.get(selectedPosition) >= 0f);
callback.onLoadProgress(progress.get(selectedPosition));
}
// Called from either a page swipe caused a lowres image to the center or an
@ -181,13 +183,36 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
}
@Override
public void setProgress(MultiImageView multiImageView, boolean progress) {
public void showProgress(MultiImageView multiImageView, boolean show) {
for (int i = 0; i < images.size(); i++) {
PostImage postImage = images.get(i);
if (postImage == multiImageView.getPostImage()) {
progress.set(i, show ? 0f : -1f);
break;
}
}
if (multiImageView.getPostImage() == images.get(selectedPosition)) {
callback.showProgress(progress.get(selectedPosition) >= 0f);
if (show) {
callback.onLoadProgress(0f);
}
}
}
@Override
public void setLinearProgress(MultiImageView multiImageView, long current, long total, boolean done) {
public void onProgress(MultiImageView multiImageView, long current, long total) {
for (int i = 0; i < images.size(); i++) {
PostImage postImage = images.get(i);
if (postImage == multiImageView.getPostImage()) {
progress.set(i, current / (float) total);
break;
}
}
if (multiImageView.getPostImage() == images.get(selectedPosition)) {
callback.onLoadProgress(progress.get(selectedPosition));
}
}
@Override
@ -232,5 +257,9 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
public void scrollTo(PostImage postImage);
public MultiImageView.Mode getImageMode(PostImage postImage);
public void showProgress(boolean show);
public void onLoadProgress(float progress);
}
}

@ -36,8 +36,6 @@ public class ImageViewerAdapter extends ViewPagerAdapter {
loadedViews.add(view);
Logger.test("getView: " + postImage.imageUrl + " " + postImage.type.toString());
return view;
}
@ -45,13 +43,8 @@ public class ImageViewerAdapter extends ViewPagerAdapter {
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
PostImage postImage = ((MultiImageView)object).getPostImage();
Logger.test("destroyView: " + postImage.imageUrl + " " + postImage.type.toString());
//noinspection SuspiciousMethodCalls
if (!loadedViews.remove((View) object)) {
Logger.test("Nope");
}
loadedViews.remove(object);
}
@Override
@ -75,7 +68,6 @@ public class ImageViewerAdapter extends ViewPagerAdapter {
public void setMode(final PostImage postImage, MultiImageView.Mode mode) {
MultiImageView view = find(postImage);
if (view == null) {
Logger.w(TAG, "setMode view not found, scheduling it");
pendingModeChanges.add(new ModeChange(mode, postImage));
} else {
view.setMode(mode);

@ -31,6 +31,7 @@ import org.floens.chan.core.presenter.ImageViewerPresenter;
import org.floens.chan.ui.adapter.ImageViewerAdapter;
import org.floens.chan.ui.toolbar.Toolbar;
import org.floens.chan.ui.view.CustomScaleImageView;
import org.floens.chan.ui.view.LoadingBar;
import org.floens.chan.ui.view.MultiImageView;
import org.floens.chan.ui.view.OptionalSwipeViewPager;
import org.floens.chan.ui.view.TransitionImageView;
@ -56,6 +57,7 @@ public class ImageViewerController extends Controller implements View.OnClickLis
private final Toolbar toolbar;
private TransitionImageView previewImage;
private OptionalSwipeViewPager pager;
private LoadingBar loadingBar;
public ImageViewerController(Context context, Toolbar toolbar) {
super(context);
@ -73,6 +75,7 @@ public class ImageViewerController extends Controller implements View.OnClickLis
previewImage = (TransitionImageView) view.findViewById(R.id.preview_image);
pager = (OptionalSwipeViewPager) view.findViewById(R.id.pager);
pager.setOnPageChangeListener(presenter);
loadingBar = (LoadingBar) view.findViewById(R.id.loading_bar);
AndroidUtils.waitForMeasure(view, new AndroidUtils.OnMeasuredCallback() {
@Override
@ -134,6 +137,14 @@ public class ImageViewerController extends Controller implements View.OnClickLis
previewCallback.scrollTo(postImage);
}
public void showProgress(boolean show) {
loadingBar.setVisibility(show ? View.VISIBLE : View.GONE);
}
public void onLoadProgress(float progress) {
loadingBar.setProgress(progress);
}
public void startPreviewInTransition(PostImage postImage) {
ImageView startImageView = getTransitionImageView(postImage);

@ -342,15 +342,15 @@ public class ImageViewFragment extends Fragment implements Callback {
}
@Override
public void setProgress(MultiImageView view, boolean progress) {
public void showProgress(MultiImageView view, boolean progress) {
showProgressBar(progress);
}
@Override
public void setLinearProgress(MultiImageView view, long current, long total, boolean done) {
public void onProgress(MultiImageView view, long current, long total) {
progressCurrent = current;
progressTotal = total;
progressDone = done;
progressDone = true;
activity.updateActionBarIfSelected(this);
}

@ -0,0 +1,52 @@
package org.floens.chan.ui.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import org.floens.chan.R;
import org.floens.chan.utils.AndroidUtils;
public class LoadingBar extends View {
private static final float MINIMUM_PROGRESS = 0.1f;
private float progress;
private Paint paint;
public LoadingBar(Context context) {
super(context);
init();
}
public LoadingBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LoadingBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void setProgress(float progress) {
progress = Math.min(Math.max(progress, 0f), 1f);
this.progress = MINIMUM_PROGRESS + progress * (1f - MINIMUM_PROGRESS);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (progress > 0f) {
canvas.drawRect(0f, 0f, getWidth() * progress, getHeight(), paint);
}
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(AndroidUtils.getAttrColor(getContext(), R.attr.colorAccent));
}
}

@ -100,7 +100,7 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
public void setMode(final Mode newMode) {
if (this.mode != newMode) {
Logger.d(TAG, "Changing mode from " + this.mode + " to " + newMode + " for " + postImage.thumbnailUrl);
// Logger.d(TAG, "Changing mode from " + this.mode + " to " + newMode + " for " + postImage.thumbnailUrl);
this.mode = newMode;
AndroidUtils.waitForMeasure(this, new AndroidUtils.OnMeasuredCallback() {
@ -177,14 +177,13 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
return;
}
callback.setProgress(this, true);
callback.showProgress(this, true);
bigImageRequest = ChanApplication.getFileCache().downloadFile(imageUrl, new FileCache.DownloadedCallback() {
@Override
public void onProgress(long downloaded, long total, boolean done) {
callback.onProgress(MultiImageView.this, downloaded, total);
if (done) {
// callback.setLinearProgress(0, 0, true);
} else {
callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
callback.showProgress(MultiImageView.this, false);
}
}
@ -217,7 +216,7 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
@Override
public void onReady() {
if (!hasContent || mode == Mode.BIGIMAGE) {
callback.setProgress(MultiImageView.this, false);
callback.showProgress(MultiImageView.this, false);
onModeLoaded(Mode.BIGIMAGE, image);
}
}
@ -235,15 +234,13 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
return;
}
callback.setProgress(this, true);
callback.showProgress(this, true);
gifRequest = ChanApplication.getFileCache().downloadFile(gifUrl, new FileCache.DownloadedCallback() {
@Override
public void onProgress(long downloaded, long total, boolean done) {
callback.onProgress(MultiImageView.this, downloaded, total);
if (done) {
callback.setProgress(MultiImageView.this, false);
callback.setLinearProgress(MultiImageView.this, 0, 0, true);
} else {
callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
callback.showProgress(MultiImageView.this, false);
}
}
@ -288,15 +285,13 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
}
public void setVideo(String videoUrl) {
callback.setProgress(this, true);
callback.showProgress(this, true);
videoRequest = ChanApplication.getFileCache().downloadFile(videoUrl, new FileCache.DownloadedCallback() {
@Override
public void onProgress(long downloaded, long total, boolean done) {
callback.onProgress(MultiImageView.this, downloaded, total);
if (done) {
callback.setProgress(MultiImageView.this, false);
callback.setLinearProgress(MultiImageView.this, 0, 0, true);
} else {
callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
callback.showProgress(MultiImageView.this, false);
}
}
@ -374,23 +369,23 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
private void onError() {
Toast.makeText(getContext(), R.string.image_preview_failed, Toast.LENGTH_SHORT).show();
callback.setProgress(this, false);
callback.showProgress(this, false);
}
private void onNotFoundError() {
callback.setProgress(this, false);
callback.showProgress(this, false);
Toast.makeText(getContext(), R.string.image_not_found, Toast.LENGTH_SHORT).show();
}
private void onOutOfMemoryError() {
Toast.makeText(getContext(), R.string.image_preview_failed_oom, Toast.LENGTH_SHORT).show();
callback.setProgress(this, false);
callback.showProgress(this, false);
}
private void onBigImageError(boolean wasInitial) {
if (wasInitial) {
Toast.makeText(getContext(), R.string.image_failed_big_image, Toast.LENGTH_SHORT).show();
callback.setProgress(this, false);
callback.showProgress(this, false);
}
}
@ -420,10 +415,6 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
cancelLoad();
}
private void onModeLoaded(Mode mode) {
onModeLoaded(mode, null);
}
private void onModeLoaded(Mode mode, View view) {
if (view != null) {
// Remove all other views
@ -448,9 +439,9 @@ public class MultiImageView extends FrameLayout implements View.OnClickListener
public static interface Callback {
public void onTap(MultiImageView multiImageView);
public void setProgress(MultiImageView multiImageView, boolean progress);
public void showProgress(MultiImageView multiImageView, boolean progress);
public void setLinearProgress(MultiImageView multiImageView, long current, long total, boolean done);
public void onProgress(MultiImageView multiImageView, long current, long total);
public void onVideoLoaded(MultiImageView multiImageView);

@ -107,6 +107,13 @@ public class AndroidUtils {
return pixels;
}
public static int getAttrColor(Context context, int attr) {
TypedArray typedArray = context.getTheme().obtainStyledAttributes(new int[]{attr});
int color = typedArray.getColor(0, 0);
typedArray.recycle();
return color;
}
public static Drawable getAttrDrawable(int attr) {
TypedArray typedArray = ChanApplication.con.getTheme().obtainStyledAttributes(new int[]{attr});
Drawable drawable = typedArray.getDrawable(0);

@ -14,5 +14,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<org.floens.chan.ui.view.LoadingBar
android:id="@+id/loading_bar"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="3dp" />
</FrameLayout>

Loading…
Cancel
Save