Fix gestures on vertical readers
This commit is contained in:
parent
bcefc176c1
commit
e53b05feba
@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.R;
|
|||||||
import eu.kanade.tachiyomi.data.source.model.Page;
|
import eu.kanade.tachiyomi.data.source.model.Page;
|
||||||
import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment;
|
import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment;
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalReader;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
@ -61,12 +62,13 @@ public class PagerReaderFragment extends BaseFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imageView.setParallelLoadingEnabled(true);
|
imageView.setParallelLoadingEnabled(true);
|
||||||
imageView.setMaxDimensions(activity.getMaxBitmapSize(), activity.getMaxBitmapSize());
|
imageView.setMaxBitmapDimensions(activity.getMaxBitmapSize());
|
||||||
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
||||||
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
||||||
imageView.setMinimumScaleType(parentFragment.scaleType);
|
imageView.setMinimumScaleType(parentFragment.scaleType);
|
||||||
imageView.setRegionDecoderClass(parentFragment.getRegionDecoderClass());
|
imageView.setRegionDecoderClass(parentFragment.getRegionDecoderClass());
|
||||||
imageView.setBitmapDecoderClass(parentFragment.getBitmapDecoderClass());
|
imageView.setBitmapDecoderClass(parentFragment.getBitmapDecoderClass());
|
||||||
|
imageView.setVerticalScroll(parentFragment instanceof VerticalReader);
|
||||||
imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent));
|
imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent));
|
||||||
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,7 +32,7 @@ public class VerticalPager extends VerticalViewPagerImpl implements Pager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void init(Context context) {
|
private void init(Context context) {
|
||||||
gestureDetector = new GestureDetector(context, new VerticalPagerGestureListener(this));
|
gestureDetector = new GestureDetector(context, new PagerGestureListener(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -119,20 +119,5 @@ public class VerticalPager extends VerticalViewPagerImpl implements Pager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class VerticalPagerGestureListener extends PagerGestureListener {
|
|
||||||
|
|
||||||
public VerticalPagerGestureListener(Pager pager) {
|
|
||||||
super(pager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDown(MotionEvent e) {
|
|
||||||
// Vertical view pager ignores scrolling events sometimes.
|
|
||||||
// Returning true here fixes it, but we lose touch events on the image like
|
|
||||||
// double tap to zoom
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.R;
|
import eu.kanade.tachiyomi.R;
|
||||||
import eu.kanade.tachiyomi.data.source.model.Page;
|
import eu.kanade.tachiyomi.data.source.model.Page;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
||||||
|
|
||||||
public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonHolder> {
|
public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonHolder> {
|
||||||
|
|
||||||
@ -64,4 +65,8 @@ public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonHolder> {
|
|||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReaderActivity getReaderActivity() {
|
||||||
|
return (ReaderActivity) fragment.getActivity();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ import butterknife.Bind;
|
|||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import eu.kanade.tachiyomi.R;
|
import eu.kanade.tachiyomi.R;
|
||||||
import eu.kanade.tachiyomi.data.source.model.Page;
|
import eu.kanade.tachiyomi.data.source.model.Page;
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
|
||||||
|
|
||||||
public class WebtoonHolder extends RecyclerView.ViewHolder {
|
public class WebtoonHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
@ -31,17 +30,16 @@ public class WebtoonHolder extends RecyclerView.ViewHolder {
|
|||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
int maxDim = ((ReaderActivity)adapter.getReader().getActivity()).getMaxBitmapSize();
|
|
||||||
|
|
||||||
imageView.setParallelLoadingEnabled(true);
|
imageView.setParallelLoadingEnabled(true);
|
||||||
|
imageView.setMaxBitmapDimensions(adapter.getReaderActivity().getMaxBitmapSize());
|
||||||
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
||||||
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
||||||
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH);
|
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH);
|
||||||
imageView.setMaxScale(10);
|
imageView.setMaxScale(10);
|
||||||
imageView.setRegionDecoderClass(adapter.getReader().getRegionDecoderClass());
|
imageView.setRegionDecoderClass(adapter.getReader().getRegionDecoderClass());
|
||||||
imageView.setBitmapDecoderClass(adapter.getReader().getBitmapDecoderClass());
|
imageView.setBitmapDecoderClass(adapter.getReader().getBitmapDecoderClass());
|
||||||
|
imageView.setVerticalScroll(true);
|
||||||
imageView.setOnTouchListener(touchListener);
|
imageView.setOnTouchListener(touchListener);
|
||||||
imageView.setMaxDimensions(maxDim, maxDim);
|
|
||||||
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onImageLoaded() {
|
public void onImageLoaded() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon;
|
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -30,7 +29,6 @@ public class WebtoonReader extends BaseReader {
|
|||||||
private Subscription decoderSubscription;
|
private Subscription decoderSubscription;
|
||||||
private GestureDetector gestureDetector;
|
private GestureDetector gestureDetector;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
|
||||||
adapter = new WebtoonAdapter(this);
|
adapter = new WebtoonAdapter(this);
|
||||||
@ -56,14 +54,6 @@ public class WebtoonReader extends BaseReader {
|
|||||||
getReaderActivity().onCenterSingleTap();
|
getReaderActivity().onCenterSingleTap();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDown(MotionEvent e) {
|
|
||||||
// The only way I've found to allow panning. Double tap event (zoom) is lost
|
|
||||||
// but panning should be the most used one
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setPages();
|
setPages();
|
||||||
|
@ -201,8 +201,12 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
private int sOrientation;
|
private int sOrientation;
|
||||||
private Rect sRegion;
|
private Rect sRegion;
|
||||||
private Rect pRegion;
|
private Rect pRegion;
|
||||||
private int cWidth;
|
|
||||||
private int cHeight;
|
// Max bitmap dimensions the device can display
|
||||||
|
private int maxBitmapDimensions;
|
||||||
|
|
||||||
|
// Vertical pagers/scrollers should enable this
|
||||||
|
private boolean isVerticalScroll;
|
||||||
|
|
||||||
// Is two-finger zooming in progress
|
// Is two-finger zooming in progress
|
||||||
private boolean isZooming;
|
private boolean isZooming;
|
||||||
@ -754,16 +758,32 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
float lastX = vTranslate.x;
|
float lastX = vTranslate.x;
|
||||||
float lastY = vTranslate.y;
|
float lastY = vTranslate.y;
|
||||||
fitToBounds(true);
|
fitToBounds(true);
|
||||||
boolean atXEdge = lastX != vTranslate.x;
|
if (!isVerticalScroll) {
|
||||||
boolean edgeXSwipe = atXEdge && dx > dy && !isPanning;
|
boolean atXEdge = lastX != vTranslate.x;
|
||||||
boolean yPan = lastY == vTranslate.y && dy > 15;
|
boolean edgeXSwipe = atXEdge && dx > dy && !isPanning;
|
||||||
if (!edgeXSwipe && (!atXEdge || yPan || isPanning)) {
|
boolean yPan = lastY == vTranslate.y && dy > 15;
|
||||||
isPanning = true;
|
|
||||||
} else if (dx > 5) {
|
if (!edgeXSwipe && (!atXEdge || yPan || isPanning)) {
|
||||||
// Haven't panned the image, and we're at the left or right edge. Switch to page swipe.
|
isPanning = true;
|
||||||
maxTouchCount = 0;
|
} else if (dx > 5) {
|
||||||
handler.removeMessages(MESSAGE_LONG_CLICK);
|
// Haven't panned the image, and we're at the left or right edge. Switch to page swipe.
|
||||||
getParent().requestDisallowInterceptTouchEvent(false);
|
maxTouchCount = 0;
|
||||||
|
handler.removeMessages(MESSAGE_LONG_CLICK);
|
||||||
|
getParent().requestDisallowInterceptTouchEvent(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
boolean atYEdge = lastY != vTranslate.y;
|
||||||
|
boolean edgeYSwipe = atYEdge && dy > dx && !isPanning;
|
||||||
|
boolean xPan = lastX == vTranslate.x && dx > 15;
|
||||||
|
|
||||||
|
if (!edgeYSwipe && (!atYEdge || xPan || isPanning)) {
|
||||||
|
isPanning = true;
|
||||||
|
} else if (dy > 5) {
|
||||||
|
// Haven't panned the image, and we're at the left or right edge. Switch to page swipe.
|
||||||
|
maxTouchCount = 0;
|
||||||
|
handler.removeMessages(MESSAGE_LONG_CLICK);
|
||||||
|
getParent().requestDisallowInterceptTouchEvent(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!panEnabled) {
|
if (!panEnabled) {
|
||||||
@ -870,7 +890,7 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When using tiles, on first render with no tile map ready, initialise it and kick off async base image loading.
|
// When using tiles, on first render with no tile map ready, initialise it and kick off async base image loading.
|
||||||
if (tileMap == null && decoder != null && cWidth == 0 && cHeight == 0) {
|
if (tileMap == null && decoder != null && maxBitmapDimensions == 0) {
|
||||||
initialiseBaseLayer(getMaxBitmapDimensions(canvas));
|
initialiseBaseLayer(getMaxBitmapDimensions(canvas));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1390,11 +1410,6 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxDimensions(int width, int height) {
|
|
||||||
cWidth = width;
|
|
||||||
cHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async task used to get image details without blocking the UI thread.
|
* Async task used to get image details without blocking the UI thread.
|
||||||
*/
|
*/
|
||||||
@ -1473,8 +1488,8 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
this.sHeight = sHeight;
|
this.sHeight = sHeight;
|
||||||
this.sOrientation = sOrientation;
|
this.sOrientation = sOrientation;
|
||||||
checkReady();
|
checkReady();
|
||||||
if (!checkImageLoaded() && cWidth != 0 && cHeight != 0) {
|
if (!checkImageLoaded() && maxBitmapDimensions > 0) {
|
||||||
initialiseBaseLayer(new Point(cWidth, cHeight));
|
initialiseBaseLayer(new Point(maxBitmapDimensions, maxBitmapDimensions));
|
||||||
}
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
requestLayout();
|
requestLayout();
|
||||||
@ -2476,6 +2491,21 @@ public class SubsamplingScaleImageView extends View {
|
|||||||
this.parallelLoadingEnabled = parallelLoadingEnabled;
|
this.parallelLoadingEnabled = parallelLoadingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set max bitmap dimensions the device can display
|
||||||
|
*/
|
||||||
|
public void setMaxBitmapDimensions(int maxBitmapDimensions) {
|
||||||
|
this.maxBitmapDimensions = maxBitmapDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set vertical scroll mode to fix gestures
|
||||||
|
*/
|
||||||
|
public void setVerticalScroll(boolean isVerticalScroll) {
|
||||||
|
this.isVerticalScroll = isVerticalScroll;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables visual debugging, showing tile boundaries and sizes.
|
* Enables visual debugging, showing tile boundaries and sizes.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user