diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/ReaderActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/ReaderActivity.java index 6c14a5869..8950bdd3f 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/activity/ReaderActivity.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/ReaderActivity.java @@ -18,12 +18,13 @@ import eu.kanade.mangafeed.data.models.Page; import eu.kanade.mangafeed.presenter.ReaderPresenter; import eu.kanade.mangafeed.ui.activity.base.BaseRxActivity; import eu.kanade.mangafeed.ui.adapter.ReaderPageAdapter; +import eu.kanade.mangafeed.widget.ReaderViewPager; import nucleus.factory.RequiresPresenter; @RequiresPresenter(ReaderPresenter.class) public class ReaderActivity extends BaseRxActivity { - @Bind(R.id.view_pager) ViewPager viewPager; + @Bind(R.id.view_pager) ReaderViewPager viewPager; @Bind(R.id.page_number) TextView pageNumber; private ReaderPageAdapter adapter; @@ -43,6 +44,12 @@ public class ReaderActivity extends BaseRxActivity { setupViewPager(); } + @Override + public void onDestroy() { + getPresenter().setCurrentPage(currentPage); + super.onDestroy(); + } + private void createAdapter() { adapter = new ReaderPageAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); @@ -67,14 +74,24 @@ public class ReaderActivity extends BaseRxActivity { } }); + viewPager.setOnChapterBoundariesOutListener(new ReaderViewPager.OnChapterBoundariesOutListener() { + @Override + public void onFirstPageOut() { + // TODO load previous chapter + } + + @Override + public void onLastPageOut() { + // TODO load next chapter + } + }); } - @Override - public void onDestroy() { - getPresenter().setCurrentPage(currentPage); - super.onDestroy(); + public ReaderViewPager getViewPager() { + return viewPager; } + public void onPageList(List pages) { adapter.setPages(pages); updatePageNumber(); @@ -104,4 +121,5 @@ public class ReaderActivity extends BaseRxActivity { } } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/ReaderPageFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/ReaderPageFragment.java index f2192e6f7..58de69606 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/ReaderPageFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/ReaderPageFragment.java @@ -12,12 +12,13 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.models.Page; +import eu.kanade.mangafeed.ui.activity.ReaderActivity; import eu.kanade.mangafeed.util.PageFileTarget; public class ReaderPageFragment extends Fragment { public static final String URL_ARGUMENT_KEY = "UrlArgumentKey"; - private SubsamplingScaleImageView mPageImageView; + private SubsamplingScaleImageView imageView; private String mUrl; @@ -53,19 +54,21 @@ public class ReaderPageFragment extends Fragment { private void loadImage() { Glide.with(getActivity()) .load(mUrl) - .downloadOnly(new PageFileTarget(mPageImageView)); + .downloadOnly(new PageFileTarget(imageView)); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - mPageImageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false); - mPageImageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); - mPageImageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE); - mPageImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE); - mPageImageView.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { + imageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false); + imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); + imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE); + imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE); + imageView.setOnTouchListener((view, motionEvent) -> + ((ReaderActivity) getActivity()).getViewPager().onImageTouch(motionEvent)); + imageView.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { @Override public void onReady() { - mPageImageView.setVisibility(View.VISIBLE); + imageView.setVisibility(View.VISIBLE); } @Override @@ -85,7 +88,7 @@ public class ReaderPageFragment extends Fragment { } }); - return mPageImageView; + return imageView; } @Override @@ -93,4 +96,5 @@ public class ReaderPageFragment extends Fragment { super.onActivityCreated(savedInstanceState); loadImage(); } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/widget/ReaderViewPager.java b/app/src/main/java/eu/kanade/mangafeed/widget/ReaderViewPager.java new file mode 100644 index 000000000..a8b9f88ad --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/widget/ReaderViewPager.java @@ -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; + } + + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml index 486e6e4a8..c4ffa0a83 100644 --- a/app/src/main/res/layout/activity_reader.xml +++ b/app/src/main/res/layout/activity_reader.xml @@ -3,11 +3,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - +