Allow tapping on the edges of the chapter to change pages
This commit is contained in:
parent
38c6fac385
commit
3a748a9453
4 changed files with 173 additions and 16 deletions
|
@ -18,12 +18,13 @@ import eu.kanade.mangafeed.data.models.Page;
|
||||||
import eu.kanade.mangafeed.presenter.ReaderPresenter;
|
import eu.kanade.mangafeed.presenter.ReaderPresenter;
|
||||||
import eu.kanade.mangafeed.ui.activity.base.BaseRxActivity;
|
import eu.kanade.mangafeed.ui.activity.base.BaseRxActivity;
|
||||||
import eu.kanade.mangafeed.ui.adapter.ReaderPageAdapter;
|
import eu.kanade.mangafeed.ui.adapter.ReaderPageAdapter;
|
||||||
|
import eu.kanade.mangafeed.widget.ReaderViewPager;
|
||||||
import nucleus.factory.RequiresPresenter;
|
import nucleus.factory.RequiresPresenter;
|
||||||
|
|
||||||
@RequiresPresenter(ReaderPresenter.class)
|
@RequiresPresenter(ReaderPresenter.class)
|
||||||
public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||||
|
|
||||||
@Bind(R.id.view_pager) ViewPager viewPager;
|
@Bind(R.id.view_pager) ReaderViewPager viewPager;
|
||||||
@Bind(R.id.page_number) TextView pageNumber;
|
@Bind(R.id.page_number) TextView pageNumber;
|
||||||
|
|
||||||
private ReaderPageAdapter adapter;
|
private ReaderPageAdapter adapter;
|
||||||
|
@ -43,6 +44,12 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||||
setupViewPager();
|
setupViewPager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
getPresenter().setCurrentPage(currentPage);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
private void createAdapter() {
|
private void createAdapter() {
|
||||||
adapter = new ReaderPageAdapter(getSupportFragmentManager());
|
adapter = new ReaderPageAdapter(getSupportFragmentManager());
|
||||||
viewPager.setAdapter(adapter);
|
viewPager.setAdapter(adapter);
|
||||||
|
@ -67,13 +74,23 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
viewPager.setOnChapterBoundariesOutListener(new ReaderViewPager.OnChapterBoundariesOutListener() {
|
||||||
|
@Override
|
||||||
|
public void onFirstPageOut() {
|
||||||
|
// TODO load previous chapter
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onLastPageOut() {
|
||||||
getPresenter().setCurrentPage(currentPage);
|
// TODO load next chapter
|
||||||
super.onDestroy();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReaderViewPager getViewPager() {
|
||||||
|
return viewPager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onPageList(List<Page> pages) {
|
public void onPageList(List<Page> pages) {
|
||||||
adapter.setPages(pages);
|
adapter.setPages(pages);
|
||||||
|
@ -104,4 +121,5 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,13 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||||
|
|
||||||
import eu.kanade.mangafeed.R;
|
import eu.kanade.mangafeed.R;
|
||||||
import eu.kanade.mangafeed.data.models.Page;
|
import eu.kanade.mangafeed.data.models.Page;
|
||||||
|
import eu.kanade.mangafeed.ui.activity.ReaderActivity;
|
||||||
import eu.kanade.mangafeed.util.PageFileTarget;
|
import eu.kanade.mangafeed.util.PageFileTarget;
|
||||||
|
|
||||||
public class ReaderPageFragment extends Fragment {
|
public class ReaderPageFragment extends Fragment {
|
||||||
public static final String URL_ARGUMENT_KEY = "UrlArgumentKey";
|
public static final String URL_ARGUMENT_KEY = "UrlArgumentKey";
|
||||||
|
|
||||||
private SubsamplingScaleImageView mPageImageView;
|
private SubsamplingScaleImageView imageView;
|
||||||
|
|
||||||
private String mUrl;
|
private String mUrl;
|
||||||
|
|
||||||
|
@ -53,19 +54,21 @@ public class ReaderPageFragment extends Fragment {
|
||||||
private void loadImage() {
|
private void loadImage() {
|
||||||
Glide.with(getActivity())
|
Glide.with(getActivity())
|
||||||
.load(mUrl)
|
.load(mUrl)
|
||||||
.downloadOnly(new PageFileTarget(mPageImageView));
|
.downloadOnly(new PageFileTarget(imageView));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
mPageImageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false);
|
imageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false);
|
||||||
mPageImageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
||||||
mPageImageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
||||||
mPageImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
|
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
|
||||||
mPageImageView.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() {
|
imageView.setOnTouchListener((view, motionEvent) ->
|
||||||
|
((ReaderActivity) getActivity()).getViewPager().onImageTouch(motionEvent));
|
||||||
|
imageView.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onReady() {
|
public void onReady() {
|
||||||
mPageImageView.setVisibility(View.VISIBLE);
|
imageView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,7 +88,7 @@ public class ReaderPageFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return mPageImageView;
|
return imageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,4 +96,5 @@ public class ReaderPageFragment extends Fragment {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
package eu.kanade.mangafeed.widget;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.GestureDetector;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
public class ReaderViewPager extends ViewPager {
|
||||||
|
|
||||||
|
private GestureDetector gestureDetector;
|
||||||
|
|
||||||
|
private OnChapterBoundariesOutListener mOnChapterBoundariesOutListener;
|
||||||
|
private OnChapterSingleTapListener mOnChapterSingleTapListener;
|
||||||
|
|
||||||
|
private static final float LEFT_REGION = 0.33f;
|
||||||
|
private static final float RIGHT_REGION = 0.66f;
|
||||||
|
private static final float SWIPE_TOLERANCE = 0.25f;
|
||||||
|
private float startDragX;
|
||||||
|
|
||||||
|
public ReaderViewPager(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
gestureDetector = new GestureDetector(getContext(), new ReaderViewGestureListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||||
|
try {
|
||||||
|
gestureDetector.onTouchEvent(ev);
|
||||||
|
|
||||||
|
if ((ev.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
|
||||||
|
if (this.getCurrentItem() == 0 || this.getCurrentItem() == this.getAdapter().getCount() - 1) {
|
||||||
|
startDragX = ev.getX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onInterceptTouchEvent(ev);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Do Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
|
try {
|
||||||
|
if (mOnChapterBoundariesOutListener != null) {
|
||||||
|
if (this.getCurrentItem() == 0) {
|
||||||
|
if ((ev.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
|
||||||
|
float displacement = ev.getX() - startDragX;
|
||||||
|
|
||||||
|
if (ev.getX() > startDragX && displacement > getWidth() * SWIPE_TOLERANCE) {
|
||||||
|
mOnChapterBoundariesOutListener.onFirstPageOut();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
startDragX = 0;
|
||||||
|
}
|
||||||
|
} else if (this.getCurrentItem() == this.getAdapter().getCount() - 1) {
|
||||||
|
if ((ev.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
|
||||||
|
float displacement = startDragX - ev.getX();
|
||||||
|
|
||||||
|
if (ev.getX() < startDragX && displacement > getWidth() * SWIPE_TOLERANCE) {
|
||||||
|
mOnChapterBoundariesOutListener.onLastPageOut();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
startDragX = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onTouchEvent(ev);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Do Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onImageTouch(MotionEvent event) {
|
||||||
|
return gestureDetector.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnChapterBoundariesOutListener {
|
||||||
|
public void onFirstPageOut();
|
||||||
|
|
||||||
|
public void onLastPageOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnChapterSingleTapListener {
|
||||||
|
public void onSingleTap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnChapterBoundariesOutListener(OnChapterBoundariesOutListener onChapterBoundariesOutListener) {
|
||||||
|
mOnChapterBoundariesOutListener = onChapterBoundariesOutListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnChapterSingleTapListener(OnChapterSingleTapListener onChapterSingleTapListener) {
|
||||||
|
mOnChapterSingleTapListener = onChapterSingleTapListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class ReaderViewGestureListener extends GestureDetector.SimpleOnGestureListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||||
|
final int position = getCurrentItem();
|
||||||
|
final float positionX = e.getX();
|
||||||
|
|
||||||
|
if (positionX < getWidth() * LEFT_REGION) {
|
||||||
|
if (position != 0) {
|
||||||
|
setCurrentItem(position - 1, true);
|
||||||
|
} else {
|
||||||
|
if (mOnChapterBoundariesOutListener != null) {
|
||||||
|
mOnChapterBoundariesOutListener.onFirstPageOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (positionX > getWidth() * RIGHT_REGION) {
|
||||||
|
if (position != getAdapter().getCount() - 1) {
|
||||||
|
setCurrentItem(position + 1, true);
|
||||||
|
} else {
|
||||||
|
if (mOnChapterBoundariesOutListener != null) {
|
||||||
|
mOnChapterBoundariesOutListener.onLastPageOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,11 +3,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager
|
<eu.kanade.mangafeed.widget.ReaderViewPager
|
||||||
android:id="@+id/view_pager"
|
android:id="@+id/view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
</android.support.v4.view.ViewPager>
|
</eu.kanade.mangafeed.widget.ReaderViewPager>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
Reference in a new issue