Some imageviewer progress

tempwork
Floens 10 years ago
parent cf7af07382
commit 3d6fe34518
  1. 20
      Clover/app/src/main/java/org/floens/chan/core/model/PostImage.java
  2. 40
      Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java
  3. 2
      Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java
  4. 35
      Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java
  5. 72
      Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java
  6. 11
      Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerNavigationController.java
  7. 7
      Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java
  8. 20
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java
  9. 100
      Clover/app/src/main/java/org/floens/chan/ui/view/MultiImageView.java
  10. 25
      Clover/app/src/main/java/org/floens/chan/ui/view/ViewPagerAdapter.java
  11. 8
      Clover/app/src/main/res/layout/controller_image_viewer.xml
  12. 2
      Clover/app/src/main/res/layout/controller_navigation_image_viewer.xml

@ -1,17 +1,35 @@
package org.floens.chan.core.model; package org.floens.chan.core.model;
public class PostImage { public class PostImage {
public enum Type {
STATIC, GIF, MOVIE
}
public String thumbnailUrl; public String thumbnailUrl;
public String imageUrl; public String imageUrl;
public String filename; public String filename;
public int imageWidth; public int imageWidth;
public int imageHeight; public int imageHeight;
public PostImage(String thumbnailUrl, String imageUrl, String filename, int imageWidth, int imageHeight) { public Type type;
public PostImage(String thumbnailUrl, String imageUrl, String filename, String extension, int imageWidth, int imageHeight) {
this.thumbnailUrl = thumbnailUrl; this.thumbnailUrl = thumbnailUrl;
this.imageUrl = imageUrl; this.imageUrl = imageUrl;
this.filename = filename; this.filename = filename;
this.imageWidth = imageWidth; this.imageWidth = imageWidth;
this.imageHeight = imageHeight; this.imageHeight = imageHeight;
switch (extension) {
case "gif":
type = Type.GIF;
break;
case "webm":
type = Type.MOVIE;
break;
default:
type = Type.STATIC;
break;
}
} }
} }

@ -0,0 +1,40 @@
package org.floens.chan.core.presenter;
import org.floens.chan.core.model.PostImage;
import java.util.List;
public class ImageViewerPresenter {
private final Callback callback;
private boolean exiting = false;
private List<PostImage> images;
private int selectedIndex;
public ImageViewerPresenter(Callback callback) {
this.callback = callback;
}
public void showImages(List<PostImage> images, int index) {
callback.startPreviewInTransition();
this.images = images;
selectedIndex = index;
}
public void onExit() {
if (exiting) return;
exiting = true;
callback.startPreviewOutTransition();
}
public void onInTransitionEnd() {
PostImage image = images.get(selectedIndex);
}
public interface Callback {
public void startPreviewInTransition();
public void startPreviewOutTransition();
}
}

@ -141,7 +141,7 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt
for (int i = 0; i < chanLoader.getThread().posts.size(); i++) { for (int i = 0; i < chanLoader.getThread().posts.size(); i++) {
Post item = chanLoader.getThread().posts.get(i); Post item = chanLoader.getThread().posts.get(i);
if (item.hasImage) { if (item.hasImage) {
images.add(new PostImage(item.thumbnailUrl, item.imageUrl, item.filename, item.imageWidth, item.imageHeight)); images.add(new PostImage(item.thumbnailUrl, item.imageUrl, item.filename, item.ext, item.imageWidth, item.imageHeight));
if (item.no == post.no) { if (item.no == post.no) {
index = i; index = i;
} }

@ -0,0 +1,35 @@
package org.floens.chan.ui.adapter;
import android.content.Context;
import android.view.View;
import org.floens.chan.core.model.PostImage;
import org.floens.chan.ui.view.MultiImageView;
import org.floens.chan.ui.view.ViewPagerAdapter;
import java.util.List;
public class ImageViewerAdapter extends ViewPagerAdapter {
private final Context context;
private final List<PostImage> images;
private final MultiImageView.Callback multiImageViewCallback;
public ImageViewerAdapter(Context context, List<PostImage> images, MultiImageView.Callback multiImageViewCallback) {
this.context = context;
this.images = images;
this.multiImageViewCallback = multiImageViewCallback;
}
@Override
public View getView(int position) {
MultiImageView view = new MultiImageView(context);
view.bindPostImage(images.get(position), multiImageViewCallback);
return view;
}
@Override
public int getCount() {
return images.size();
}
}

@ -11,6 +11,7 @@ import android.graphics.Color;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.support.v4.view.ViewPager;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
@ -18,52 +19,70 @@ import android.widget.ImageView;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.controller.Controller; import org.floens.chan.controller.Controller;
import org.floens.chan.core.presenter.ImageViewerPresenter;
import org.floens.chan.ui.toolbar.Toolbar;
import org.floens.chan.ui.view.ClippingImageView; import org.floens.chan.ui.view.ClippingImageView;
import org.floens.chan.utils.AnimationUtils; import org.floens.chan.utils.AnimationUtils;
import org.floens.chan.utils.Logger;
import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AnimationUtils.calculateBoundsAnimation; import static org.floens.chan.utils.AnimationUtils.calculateBoundsAnimation;
public class ImageViewerController extends Controller implements View.OnClickListener { public class ImageViewerController extends Controller implements View.OnClickListener, ImageViewerPresenter.Callback {
private static final int TRANSITION_DURATION = 200; //165; private static final int TRANSITION_DURATION = 200; //165;
private static final int TRANSITION_CLIP_DURATION = (int) (TRANSITION_DURATION * 0.5f); private static final int TRANSITION_CLIP_DURATION = (int) (TRANSITION_DURATION * 0.5f);
private static final float TRANSITION_FINAL_ALPHA = 0.80f; private static final float TRANSITION_FINAL_ALPHA = 0.80f;
private ClippingImageView previewImage;
private Callback callback;
private int statusBarColorPrevious; private int statusBarColorPrevious;
private AnimatorSet startPreviewAnimation; private AnimatorSet startPreviewAnimation;
private AnimatorSet endAnimation; private AnimatorSet endAnimation;
public ImageViewerController(Context context) { private Callback callback;
private ImageViewerPresenter presenter;
private final Toolbar toolbar;
private ClippingImageView previewImage;
private ViewPager pager;
public ImageViewerController(Context context, Toolbar toolbar) {
super(context); super(context);
this.toolbar = toolbar;
presenter = new ImageViewerPresenter(this);
} }
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
navigationItem.title = "Image title here";
view = inflateRes(R.layout.controller_image_viewer); view = inflateRes(R.layout.controller_image_viewer);
previewImage = (ClippingImageView) view.findViewById(R.id.image);
view.setOnClickListener(this); view.setOnClickListener(this);
previewImage = (ClippingImageView) view.findViewById(R.id.preview_image);
pager = (ViewPager) view.findViewById(R.id.pager);
} }
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startPreviewOutTransition(); presenter.onExit();
} }
@Override @Override
public boolean onBack() { public boolean onBack() {
startPreviewOutTransition(); presenter.onExit();
return true; return true;
} }
public void startPreviewInTransition(Callback callback, final ImageView previewImageView) { public void setCallback(Callback callback) {
this.callback = callback; this.callback = callback;
}
public ImageViewerPresenter getPresenter() {
return presenter;
}
public void startPreviewInTransition() {
ImageView previewImageView = callback.getPreviewImageStartView(this);
previewImage.setImageDrawable(previewImageView.getDrawable()); previewImage.setImageDrawable(previewImageView.getDrawable());
Rect startBounds = getImageViewBounds(previewImageView); Rect startBounds = getImageViewBounds(previewImageView);
@ -127,6 +146,11 @@ public class ImageViewerController extends Controller implements View.OnClickLis
startPreviewAnimation.setInterpolator(new DecelerateInterpolator()); startPreviewAnimation.setInterpolator(new DecelerateInterpolator());
startPreviewAnimation.addListener(new AnimatorListenerAdapter() { startPreviewAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
callback.onPreviewCreate(ImageViewerController.this);
}
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
previewImage.setX(0f); previewImage.setX(0f);
@ -135,6 +159,7 @@ public class ImageViewerController extends Controller implements View.OnClickLis
previewImage.setScaleY(1f); previewImage.setScaleY(1f);
previewImage.clip(null); previewImage.clip(null);
startPreviewAnimation = null; startPreviewAnimation = null;
presenter.onInTransitionEnd();
} }
}); });
startPreviewAnimation.start(); startPreviewAnimation.start();
@ -220,23 +245,27 @@ public class ImageViewerController extends Controller implements View.OnClickLis
} }
private void previewOutAnimationEnded() { private void previewOutAnimationEnded() {
setStatusBarColor(statusBarColorPrevious); setBackgroundAlpha(0f);
callback.onPreviewDestroy(this); callback.onPreviewDestroy(this);
navigationController.stopPresenting(false); navigationController.stopPresenting(false);
} }
private void setBackgroundAlpha(float alpha) { private void setBackgroundAlpha(float alpha) {
alpha *= TRANSITION_FINAL_ALPHA; view.setBackgroundColor(Color.argb((int) (alpha * TRANSITION_FINAL_ALPHA * 255f), 0, 0, 0));
view.setBackgroundColor(Color.argb((int) (alpha * 255f), 0, 0, 0));
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
int r = (int) ((1f - alpha) * Color.red(statusBarColorPrevious)); if (alpha == 0f) {
int g = (int) ((1f - alpha) * Color.green(statusBarColorPrevious)); setStatusBarColor(statusBarColorPrevious);
int b = (int) ((1f - alpha) * Color.blue(statusBarColorPrevious)); } else {
int r = (int) ((1f - alpha) * Color.red(statusBarColorPrevious));
setStatusBarColor(Color.argb(255, r, g, b)); int g = (int) ((1f - alpha) * Color.green(statusBarColorPrevious));
int b = (int) ((1f - alpha) * Color.blue(statusBarColorPrevious));
setStatusBarColor(Color.argb(255, r, g, b));
}
} }
setToolbarBackgroundAlpha(alpha);
} }
private void setStatusBarColor(int color) { private void setStatusBarColor(int color) {
@ -245,12 +274,15 @@ public class ImageViewerController extends Controller implements View.OnClickLis
} }
} }
private void setToolbarBackgroundAlpha(float alpha) {
toolbar.setAlpha(alpha);
}
private Rect getImageViewBounds(ImageView image) { private Rect getImageViewBounds(ImageView image) {
Rect startBounds = new Rect(); Rect startBounds = new Rect();
if (image.getGlobalVisibleRect(startBounds) && !startBounds.isEmpty()) { if (image.getGlobalVisibleRect(startBounds) && !startBounds.isEmpty()) {
AnimationUtils.adjustImageViewBoundsToDrawableBounds(image, startBounds); AnimationUtils.adjustImageViewBoundsToDrawableBounds(image, startBounds);
if (!startBounds.isEmpty()) { if (!startBounds.isEmpty()) {
Logger.test(startBounds.toShortString());
return startBounds; return startBounds;
} else { } else {
return null; return null;
@ -271,6 +303,8 @@ public class ImageViewerController extends Controller implements View.OnClickLis
public interface Callback { public interface Callback {
public ImageView getPreviewImageStartView(ImageViewerController imageViewerController); public ImageView getPreviewImageStartView(ImageViewerController imageViewerController);
public void onPreviewCreate(ImageViewerController imageViewerController);
public void onPreviewDestroy(ImageViewerController imageViewerController); public void onPreviewDestroy(ImageViewerController imageViewerController);
} }
} }

@ -3,13 +3,15 @@ package org.floens.chan.ui.controller;
import android.content.Context; import android.content.Context;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.controller.NavigationController; import org.floens.chan.controller.NavigationController;
import org.floens.chan.core.model.PostImage;
import org.floens.chan.ui.toolbar.Toolbar; import org.floens.chan.ui.toolbar.Toolbar;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import java.util.List;
public class ImageViewerNavigationController extends NavigationController { public class ImageViewerNavigationController extends NavigationController {
private ImageViewerController imageViewerController; private ImageViewerController imageViewerController;
@ -27,15 +29,16 @@ public class ImageViewerNavigationController extends NavigationController {
toolbar.setCallback(this); toolbar.setCallback(this);
imageViewerController = new ImageViewerController(context); imageViewerController = new ImageViewerController(context, toolbar);
pushController(imageViewerController, false); pushController(imageViewerController, false);
} }
public void setImage(final ImageViewerController.Callback callback, final ImageView startImageView) { public void showImages(final List<PostImage> images, final int index, final ImageViewerController.Callback callback) {
AndroidUtils.waitForMeasure(imageViewerController.view, new AndroidUtils.OnMeasuredCallback() { AndroidUtils.waitForMeasure(imageViewerController.view, new AndroidUtils.OnMeasuredCallback() {
@Override @Override
public boolean onMeasured(View view) { public boolean onMeasured(View view) {
imageViewerController.startPreviewInTransition(callback, startImageView); imageViewerController.setCallback(callback);
imageViewerController.getPresenter().showImages(images, index);
return true; return true;
} }
}); });

@ -25,11 +25,10 @@ public abstract class ThreadController extends Controller implements ThreadLayou
@Override @Override
public void showImages(List<PostImage> images, int index, final ImageView thumbnail) { public void showImages(List<PostImage> images, int index, final ImageView thumbnail) {
presentingImageView = thumbnail; presentingImageView = thumbnail;
presentingImageView.setVisibility(View.INVISIBLE);
final ImageViewerNavigationController imageViewerNavigationController = new ImageViewerNavigationController(context); final ImageViewerNavigationController imageViewerNavigationController = new ImageViewerNavigationController(context);
presentController(imageViewerNavigationController, false); presentController(imageViewerNavigationController, false);
imageViewerNavigationController.setImage(this, thumbnail); imageViewerNavigationController.showImages(images, index, this);
} }
@Override @Override
@ -37,6 +36,10 @@ public abstract class ThreadController extends Controller implements ThreadLayou
return presentingImageView; return presentingImageView;
} }
public void onPreviewCreate(ImageViewerController imageViewerController) {
presentingImageView.setVisibility(View.INVISIBLE);
}
@Override @Override
public void onPreviewDestroy(ImageViewerController imageViewerController) { public void onPreviewDestroy(ImageViewerController imageViewerController) {
presentingImageView.setVisibility(View.VISIBLE); presentingImageView.setVisibility(View.VISIBLE);

@ -40,8 +40,8 @@ import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.ui.activity.ImageViewActivity; import org.floens.chan.ui.activity.ImageViewActivity;
import org.floens.chan.ui.adapter.ImageViewAdapter; import org.floens.chan.ui.adapter.ImageViewAdapter;
import org.floens.chan.ui.view.ThumbnailImageView; import org.floens.chan.ui.view.MultiImageView;
import org.floens.chan.ui.view.ThumbnailImageView.ThumbnailImageViewCallback; import org.floens.chan.ui.view.MultiImageView.Callback;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.ImageSaver; import org.floens.chan.utils.ImageSaver;
@ -49,11 +49,11 @@ import java.io.File;
import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.dp;
public class ImageViewFragment extends Fragment implements ThumbnailImageViewCallback { public class ImageViewFragment extends Fragment implements Callback {
private Context context; private Context context;
private ImageViewActivity activity; private ImageViewActivity activity;
private ThumbnailImageView imageView; private MultiImageView imageView;
private Post post; private Post post;
private boolean showProgressBar = true; private boolean showProgressBar = true;
@ -83,7 +83,7 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal
} else { } else {
context = inflater.getContext(); context = inflater.getContext();
imageView = new ThumbnailImageView(context); imageView = new MultiImageView(context);
imageView.setCallback(this); imageView.setCallback(this);
int padding = getResources().getDimensionPixelSize(R.dimen.image_view_padding); int padding = getResources().getDimensionPixelSize(R.dimen.image_view_padding);
imageView.setPadding(padding, padding, padding, padding); imageView.setPadding(padding, padding, padding, padding);
@ -272,7 +272,7 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal
context.startActivity(Intent.createChooser(intent, context.getString(R.string.action_share))); context.startActivity(Intent.createChooser(intent, context.getString(R.string.action_share)));
} }
public void onVideoError(File video) { public void onVideoError(MultiImageView view, File video) {
if (ChanSettings.getVideoErrorIgnore()) { if (ChanSettings.getVideoErrorIgnore()) {
Toast.makeText(context, R.string.image_open_failed, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.image_open_failed, Toast.LENGTH_SHORT).show();
} else { } else {
@ -324,7 +324,7 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal
} }
@Override @Override
public void onTap() { public void onTap(MultiImageView view) {
if (tapToLoad) { if (tapToLoad) {
if (loaded) { if (loaded) {
activity.finish(); activity.finish();
@ -337,12 +337,12 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal
} }
@Override @Override
public void setProgress(boolean progress) { public void setProgress(MultiImageView view, boolean progress) {
showProgressBar(progress); showProgressBar(progress);
} }
@Override @Override
public void setLinearProgress(long current, long total, boolean done) { public void setLinearProgress(MultiImageView view, long current, long total, boolean done) {
progressCurrent = current; progressCurrent = current;
progressTotal = total; progressTotal = total;
progressDone = done; progressDone = done;
@ -350,7 +350,7 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal
} }
@Override @Override
public void onVideoLoaded() { public void onVideoLoaded(MultiImageView view) {
videoSetIconToPause = true; videoSetIconToPause = true;
activity.invalidateActionBar(); activity.invalidateActionBar();
} }

@ -30,13 +30,13 @@ import android.widget.ImageView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.VideoView; import android.widget.VideoView;
import com.android.volley.Request;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader.ImageContainer; import com.android.volley.toolbox.ImageLoader.ImageContainer;
import com.koushikdutta.async.future.Future; import com.koushikdutta.async.future.Future;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.model.PostImage;
import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.FileCache; import org.floens.chan.utils.FileCache;
@ -48,34 +48,28 @@ import java.io.IOException;
import pl.droidsonroids.gif.GifDrawable; import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView; import pl.droidsonroids.gif.GifImageView;
public class ThumbnailImageView extends LoadView implements View.OnClickListener { public class MultiImageView extends LoadView implements View.OnClickListener {
private static final String TAG = "ThumbnailImageView"; private static final String TAG = "MultiImageView";
private ThumbnailImageViewCallback callback; private PostImage postImage;
private Callback callback;
/**
* Max amount to scale the image inside the view
*/
private final float maxScale = 3f;
private boolean thumbnailNeeded = true; private boolean thumbnailNeeded = true;
private Request<?> imageRequest; private Future<?> request;
private Future<?> ionRequest;
private VideoView videoView; private VideoView videoView;
private GifDrawable gifDrawable;
public ThumbnailImageView(Context context) { public MultiImageView(Context context) {
super(context); super(context);
init(); init();
} }
public ThumbnailImageView(Context context, AttributeSet attrs) { public MultiImageView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
init(); init();
} }
public ThumbnailImageView(Context context, AttributeSet attrs, int defStyleAttr) { public MultiImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
init(); init();
} }
@ -84,10 +78,21 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
setOnClickListener(this); setOnClickListener(this);
} }
public void setCallback(ThumbnailImageViewCallback callback) { public void bindPostImage(PostImage postImage, Callback callback) {
this.postImage = postImage;
this.callback = callback; this.callback = callback;
} }
public void loadLowRes() {
}
public void loadHighRes() {
}
public void setCallback(Callback callback) {
this.callback = callback;
}
public void setThumbnail(String thumbnailUrl) { public void setThumbnail(String thumbnailUrl) {
if (getWidth() == 0 || getHeight() == 0) { if (getWidth() == 0 || getHeight() == 0) {
@ -120,15 +125,15 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
return; return;
} }
callback.setProgress(true); callback.setProgress(this, true);
ionRequest = ChanApplication.getFileCache().downloadFile(getContext(), imageUrl, new FileCache.DownloadedCallback() { request = ChanApplication.getFileCache().downloadFile(getContext(), imageUrl, new FileCache.DownloadedCallback() {
@Override @Override
public void onProgress(long downloaded, long total, boolean done) { public void onProgress(long downloaded, long total, boolean done) {
if (done) { if (done) {
// callback.setLinearProgress(0, 0, true); // callback.setLinearProgress(0, 0, true);
thumbnailNeeded = false; thumbnailNeeded = false;
} else { } else {
callback.setLinearProgress(downloaded, total, false); callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
} }
} }
@ -151,7 +156,7 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
public void setBigImageFile(File file) { public void setBigImageFile(File file) {
final CustomScaleImageView image = new CustomScaleImageView(getContext()); final CustomScaleImageView image = new CustomScaleImageView(getContext());
image.setImageFile(file.getAbsolutePath()); image.setImageFile(file.getAbsolutePath());
image.setOnClickListener(ThumbnailImageView.this); image.setOnClickListener(MultiImageView.this);
addView(image); addView(image);
@ -160,7 +165,7 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
public void onInit() { public void onInit() {
removeAllViews(); removeAllViews();
addView(image); addView(image);
callback.setProgress(false); callback.setProgress(MultiImageView.this, false);
} }
@Override @Override
@ -176,16 +181,16 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
return; return;
} }
callback.setProgress(true); callback.setProgress(this, true);
ionRequest = ChanApplication.getFileCache().downloadFile(getContext(), gifUrl, new FileCache.DownloadedCallback() { request = ChanApplication.getFileCache().downloadFile(getContext(), gifUrl, new FileCache.DownloadedCallback() {
@Override @Override
public void onProgress(long downloaded, long total, boolean done) { public void onProgress(long downloaded, long total, boolean done) {
if (done) { if (done) {
callback.setProgress(false); callback.setProgress(MultiImageView.this, false);
callback.setLinearProgress(0, 0, true); callback.setLinearProgress(MultiImageView.this, 0, 0, true);
thumbnailNeeded = false; thumbnailNeeded = false;
} else { } else {
callback.setLinearProgress(downloaded, total, false); callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
} }
} }
@ -227,16 +232,16 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
} }
public void setVideo(String videoUrl) { public void setVideo(String videoUrl) {
callback.setProgress(true); callback.setProgress(this, true);
ionRequest = ChanApplication.getFileCache().downloadFile(getContext(), videoUrl, new FileCache.DownloadedCallback() { request = ChanApplication.getFileCache().downloadFile(getContext(), videoUrl, new FileCache.DownloadedCallback() {
@Override @Override
public void onProgress(long downloaded, long total, boolean done) { public void onProgress(long downloaded, long total, boolean done) {
if (done) { if (done) {
callback.setProgress(false); callback.setProgress(MultiImageView.this, false);
callback.setLinearProgress(0, 0, true); callback.setLinearProgress(MultiImageView.this, 0, 0, true);
thumbnailNeeded = false; thumbnailNeeded = false;
} else { } else {
callback.setLinearProgress(downloaded, total, false); callback.setLinearProgress(MultiImageView.this, downloaded, total, false);
} }
} }
@ -282,13 +287,13 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
@Override @Override
public void onPrepared(MediaPlayer mp) { public void onPrepared(MediaPlayer mp) {
mp.setLooping(true); mp.setLooping(true);
callback.onVideoLoaded(); callback.onVideoLoaded(MultiImageView.this);
} }
}); });
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override @Override
public boolean onError(MediaPlayer mp, int what, int extra) { public boolean onError(MediaPlayer mp, int what, int extra) {
callback.onVideoError(file); callback.onVideoError(MultiImageView.this, file);
return true; return true;
} }
@ -308,45 +313,40 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
public void onError() { public void onError() {
Toast.makeText(getContext(), R.string.image_preview_failed, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), R.string.image_preview_failed, Toast.LENGTH_SHORT).show();
callback.setProgress(false); callback.setProgress(this, false);
} }
public void onNotFoundError() { public void onNotFoundError() {
Toast.makeText(getContext(), R.string.image_not_found, Toast.LENGTH_LONG).show(); Toast.makeText(getContext(), R.string.image_not_found, Toast.LENGTH_LONG).show();
callback.setProgress(false); callback.setProgress(this, false);
} }
public void onOutOfMemoryError() { public void onOutOfMemoryError() {
Toast.makeText(getContext(), R.string.image_preview_failed_oom, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), R.string.image_preview_failed_oom, Toast.LENGTH_SHORT).show();
callback.setProgress(false); callback.setProgress(this, false);
} }
public void cancelLoad() { public void cancelLoad() {
if (imageRequest != null) { if (request != null) {
imageRequest.cancel(); request.cancel(true);
imageRequest = null;
}
if (ionRequest != null) {
ionRequest.cancel(true);
} }
} }
@Override @Override
public void onClick(View v) { public void onClick(View v) {
callback.onTap(); callback.onTap(this);
} }
public static interface ThumbnailImageViewCallback { public static interface Callback {
public void onTap(); public void onTap(MultiImageView multiImageView);
public void setProgress(boolean progress); public void setProgress(MultiImageView multiImageView, boolean progress);
public void setLinearProgress(long current, long total, boolean done); public void setLinearProgress(MultiImageView multiImageView, long current, long total, boolean done);
public void onVideoLoaded(); public void onVideoLoaded(MultiImageView multiImageView);
public void onVideoError(File video); public void onVideoError(MultiImageView multiImageView, File video);
} }
public static class NoMusicServiceCommandContext extends ContextWrapper { public static class NoMusicServiceCommandContext extends ContextWrapper {

@ -0,0 +1,25 @@
package org.floens.chan.ui.view;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import org.floens.chan.utils.AndroidUtils;
public abstract class ViewPagerAdapter extends PagerAdapter {
@Override
public Object instantiateItem(ViewGroup container, int position) {
return getView(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
AndroidUtils.removeFromParentView((View) object);
}
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
public abstract View getView(int position);
}

@ -4,8 +4,14 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<org.floens.chan.ui.view.ClippingImageView <org.floens.chan.ui.view.ClippingImageView
android:id="@+id/image" android:id="@+id/preview_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>

@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
android:background="@color/primary" android:background="#e9000000"
android:elevation="4dp" /> android:elevation="4dp" />
<FrameLayout <FrameLayout

Loading…
Cancel
Save