From a06f2b928389b9347546d3f096a4b72af271551b Mon Sep 17 00:00:00 2001 From: Floens Date: Sun, 29 Mar 2015 20:23:28 +0200 Subject: [PATCH] Add a progressbar to the imageviewer --- .../core/presenter/ImageViewerPresenter.java | 47 +++++++++++++---- .../chan/ui/adapter/ImageViewerAdapter.java | 10 +--- .../ui/controller/ImageViewerController.java | 11 ++++ .../chan/ui/fragment/ImageViewFragment.java | 6 +-- .../org/floens/chan/ui/view/LoadingBar.java | 52 +++++++++++++++++++ .../floens/chan/ui/view/MultiImageView.java | 43 ++++++--------- .../org/floens/chan/utils/AndroidUtils.java | 7 +++ .../res/layout/controller_image_viewer.xml | 5 ++ 8 files changed, 134 insertions(+), 47 deletions(-) create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/view/LoadingBar.java diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java index 65b42484..db8be677 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java @@ -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 images; + private List 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); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java index ffec69db..66e314bc 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java @@ -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); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java index c1d2678a..ae1785de 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java @@ -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); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java index cc4f5ce5..4702b817 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java @@ -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); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/LoadingBar.java b/Clover/app/src/main/java/org/floens/chan/ui/view/LoadingBar.java new file mode 100644 index 00000000..a3af7010 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/LoadingBar.java @@ -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)); + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java index 58d84414..6691a5c7 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java @@ -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); diff --git a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java index 1ad91139..6e5ace0a 100644 --- a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java +++ b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java @@ -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); diff --git a/Clover/app/src/main/res/layout/controller_image_viewer.xml b/Clover/app/src/main/res/layout/controller_image_viewer.xml index 27cf88bf..9d0daabc 100644 --- a/Clover/app/src/main/res/layout/controller_image_viewer.xml +++ b/Clover/app/src/main/res/layout/controller_image_viewer.xml @@ -14,5 +14,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> +