From 631ef65502830128698fb8b8c570ddfa3285c60a Mon Sep 17 00:00:00 2001
From: inorichi <chibilen@gmail.com>
Date: Mon, 4 Jan 2016 01:31:15 +0100
Subject: [PATCH] Host readers inside a fragment (Avoids some leaks)

---
 .../mangafeed/ui/reader/ReaderActivity.java   | 34 +++-----
 .../mangafeed/ui/reader/ReaderMenu.java       |  5 +-
 .../mangafeed/ui/reader/ReaderPresenter.java  |  6 +-
 .../ui/reader/viewer/base/BaseReader.java     | 55 ++++++-------
 .../viewer/common/ViewPagerInterface.java     |  8 ++
 .../reader/viewer/common/ViewPagerReader.java | 81 +++++++++++--------
 .../viewer/common/ViewPagerReaderAdapter.java | 14 ++--
 .../common/ViewPagerReaderFragment.java       |  6 +-
 .../viewer/horizontal/HorizontalReader.java   | 27 +++----
 .../horizontal/HorizontalViewPager.java       | 11 +++
 .../viewer/horizontal/LeftToRightReader.java  |  6 --
 .../viewer/horizontal/RightToLeftReader.java  | 19 +++--
 .../viewer/vertical/VerticalReader.java       | 27 +++----
 .../viewer/vertical/VerticalViewPager.java    | 13 ++-
 .../reader/viewer/webtoon/WebtoonAdapter.java | 65 +++++++++------
 .../reader/viewer/webtoon/WebtoonReader.java  | 67 ++++++++++-----
 app/src/main/res/layout/reader_horizontal.xml |  7 --
 app/src/main/res/layout/reader_vertical.xml   |  8 --
 18 files changed, 248 insertions(+), 211 deletions(-)
 delete mode 100644 app/src/main/res/layout/reader_horizontal.xml
 delete mode 100644 app/src/main/res/layout/reader_vertical.xml

diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java
index 3ef2f829dd..7101716f54 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java
@@ -11,9 +11,7 @@ import android.support.v4.content.ContextCompat;
 import android.support.v7.widget.Toolbar;
 import android.view.Surface;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import java.util.List;
@@ -45,7 +43,6 @@ import rx.subscriptions.CompositeSubscription;
 public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
 
     @Bind(R.id.page_number) TextView pageNumber;
-    @Bind(R.id.reader) FrameLayout container;
     @Bind(R.id.toolbar) Toolbar toolbar;
 
     @Inject PreferencesHelper preferences;
@@ -103,15 +100,14 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
     @Override
     protected void onPause() {
         if (viewer != null)
-            getPresenter().setCurrentPage(viewer.getCurrentPosition());
+            getPresenter().setCurrentPage(viewer.getCurrentPage());
         super.onPause();
     }
 
     @Override
     protected void onDestroy() {
         subscriptions.unsubscribe();
-        if (viewer != null)
-            viewer.destroy();
+        viewer = null;
         super.onDestroy();
     }
 
@@ -126,13 +122,13 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
         ToastUtil.showShort(this, R.string.page_list_error);
     }
 
-    public void onChapterReady(List<Page> pages, Manga manga, Chapter chapter) {
-        if (viewer != null)
-            viewer.destroy();
-        viewer = createViewer(manga);
-        viewer.onPageListReady(pages);
-        viewer.updatePageNumber();
-        readerMenu.onChapterReady(pages.size(), manga, chapter);
+    public void onChapterReady(List<Page> pages, Manga manga, Chapter chapter, int currentPage) {
+        if (viewer == null) {
+            viewer = createViewer(manga);
+            getSupportFragmentManager().beginTransaction().replace(R.id.reader, viewer).commit();
+        }
+        viewer.onPageListReady(pages, currentPage);
+        readerMenu.onChapterReady(pages.size(), manga, chapter, currentPage);
     }
 
     private BaseReader createViewer(Manga manga) {
@@ -140,13 +136,13 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
 
         switch (mangaViewer) {
             case LEFT_TO_RIGHT: default:
-                return new LeftToRightReader(this);
+                return new LeftToRightReader();
             case RIGHT_TO_LEFT:
-                return new RightToLeftReader(this);
+                return new RightToLeftReader();
             case VERTICAL:
-                return new VerticalReader(this);
+                return new VerticalReader();
             case WEBTOON:
-                return new WebtoonReader(this);
+                return new WebtoonReader();
         }
     }
 
@@ -279,10 +275,6 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
         return readerTheme;
     }
 
-    public ViewGroup getContainer() {
-        return container;
-    }
-
     public PreferencesHelper getPreferences() {
         return preferences;
     }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java
index 2914dfc749..48a5b87aa9 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java
@@ -106,7 +106,7 @@ public class ReaderMenu {
         showing = false;
     }
 
-    public void onChapterReady(int numPages, Manga manga, Chapter chapter) {
+    public void onChapterReady(int numPages, Manga manga, Chapter chapter, int currentPageIndex) {
         if (manga.viewer == ReaderActivity.RIGHT_TO_LEFT && !inverted) {
             // Invert the seekbar and textview fields for the right to left reader
             seekBar.setRotation(180);
@@ -119,7 +119,8 @@ public class ReaderMenu {
 
         // Set initial values
         totalPages.setText("" + numPages);
-        currentPage.setText("" + (chapter.last_page_read + 1));
+        currentPage.setText("" + (currentPageIndex + 1));
+        seekBar.setProgress(currentPageIndex);
         seekBar.setMax(numPages - 1);
 
         activity.setToolbarTitle(manga.title);
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
index 6b47ff820c..1368e08e37 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
@@ -90,11 +90,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
                             start(GET_PAGE_IMAGES);
                             start(RETRY_IMAGES);
                         }),
-                (view, pages) -> {
-                    view.onChapterReady(pages, manga, chapter);
-                    if (currentPage != 0)
-                        view.setSelectedPage(currentPage);
-                },
+                (view, pages) -> view.onChapterReady(pages, manga, chapter, currentPage),
                 (view, error) -> view.onChapterError());
 
         registerForStickyEvents();
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java
index a8c6b9b033..1bf05fd399 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java
@@ -1,71 +1,72 @@
 package eu.kanade.mangafeed.ui.reader.viewer.base;
 
 import android.view.MotionEvent;
-import android.view.ViewGroup;
 
 import java.util.List;
 
 import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.source.model.Page;
+import eu.kanade.mangafeed.ui.base.fragment.BaseFragment;
 import eu.kanade.mangafeed.ui.reader.ReaderActivity;
 import eu.kanade.mangafeed.ui.reader.ReaderPresenter;
 import eu.kanade.mangafeed.util.ToastUtil;
 
-public abstract class BaseReader {
+public abstract class BaseReader extends BaseFragment {
 
-    protected ReaderActivity activity;
-    protected ReaderPresenter presenter;
-    protected ViewGroup container;
-    protected int currentPosition;
-
-    public BaseReader(ReaderActivity activity) {
-        this.activity = activity;
-        this.container = activity.getContainer();
-        this.presenter = activity.getPresenter();
-    }
+    protected int currentPage;
+    protected List<Page> pages;
 
     public void updatePageNumber() {
-        activity.onPageChanged(getCurrentPosition(), getTotalPages());
+        getReaderActivity().onPageChanged(getCurrentPage(), getTotalPages());
     }
 
-    // Returns the page index given a position in the viewer. Useful por a right to left viewer,
-    // where the current page is the inverse of the position
-    public int getCurrentPageIndex(int viewerPosition) {
-        return viewerPosition;
+    public int getCurrentPage() {
+        return currentPage;
     }
 
-    public int getCurrentPosition() {
-        return getCurrentPageIndex(currentPosition);
+    public int getPageForPosition(int position) {
+        return position;
+    }
+
+    public int getPositionForPage(int page) {
+        return page;
     }
 
     public void requestNextChapter() {
+        ReaderPresenter presenter = getReaderActivity().getPresenter();
         if (presenter.hasNextChapter()) {
-            presenter.setCurrentPage(getCurrentPosition());
+            presenter.setCurrentPage(getCurrentPage());
             presenter.loadNextChapter();
         } else {
-            ToastUtil.showShort(activity, R.string.no_next_chapter);
+            ToastUtil.showShort(getActivity(), R.string.no_next_chapter);
         }
 
     }
 
     public void requestPreviousChapter() {
+        ReaderPresenter presenter = getReaderActivity().getPresenter();
         if (presenter.hasPreviousChapter()) {
-            presenter.setCurrentPage(getCurrentPosition());
+            presenter.setCurrentPage(getCurrentPage());
             presenter.loadPreviousChapter();
         } else {
-            ToastUtil.showShort(activity, R.string.no_previous_chapter);
+            ToastUtil.showShort(getActivity(), R.string.no_previous_chapter);
         }
     }
 
     public void onPageChanged(int position) {
-        currentPosition = position;
+        currentPage = getPageForPosition(position);
         updatePageNumber();
     }
 
-    public void destroy() {}
+    public int getTotalPages() {
+        return pages == null ? 0 : pages.size();
+    }
 
-    public abstract int getTotalPages();
     public abstract void setSelectedPage(int pageNumber);
-    public abstract void onPageListReady(List<Page> pages);
+    public abstract void onPageListReady(List<Page> pages, int currentPage);
     public abstract boolean onImageTouch(MotionEvent motionEvent);
+
+    public ReaderActivity getReaderActivity() {
+        return (ReaderActivity) getActivity();
+    }
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerInterface.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerInterface.java
index 2c2304e102..604081ba9f 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerInterface.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerInterface.java
@@ -2,9 +2,15 @@ package eu.kanade.mangafeed.ui.reader.viewer.common;
 
 import android.support.v4.view.PagerAdapter;
 import android.view.MotionEvent;
+import android.view.ViewGroup;
+
+import rx.functions.Action1;
 
 public interface ViewPagerInterface {
 
+    void setId(int id);
+    void setLayoutParams(ViewGroup.LayoutParams layoutParams);
+
     void setOffscreenPageLimit(int limit);
 
     int getCurrentItem();
@@ -24,4 +30,6 @@ public interface ViewPagerInterface {
     OnChapterBoundariesOutListener getChapterBoundariesListener();
     OnChapterSingleTapListener getChapterSingleTapListener();
 
+    void setOnPageChangeListener(Action1<Integer> onPageChanged);
+    void clearOnPageChangeListeners();
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReader.java
index 912fbd0395..860ec92bb3 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReader.java
@@ -1,33 +1,31 @@
 package eu.kanade.mangafeed.ui.reader.viewer.common;
 
-import android.support.annotation.CallSuper;
 import android.view.MotionEvent;
+import android.view.ViewGroup;
 
 import java.util.List;
 
+import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.source.model.Page;
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
 import eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
 import rx.Subscription;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public abstract class ViewPagerReader extends BaseReader {
 
     protected ViewPagerReaderAdapter adapter;
-    protected ViewPagerInterface viewPager;
+    protected ViewPagerInterface pager;
 
     protected boolean transitions;
     protected Subscription transitionsSubscription;
 
-    public ViewPagerReader(ReaderActivity activity) {
-        super(activity);
-
-        transitionsSubscription = activity.getPreferences().enableTransitions().asObservable()
-                .subscribe(value -> transitions = value);
-    }
-
-    protected void initializeViewPager() {
-        viewPager.setOffscreenPageLimit(2);
-        viewPager.setOnChapterBoundariesOutListener(new OnChapterBoundariesOutListener() {
+    protected void initializePager(ViewPagerInterface pager) {
+        this.pager = pager;
+        pager.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+        pager.setOffscreenPageLimit(2);
+        pager.setId(R.id.view_pager);
+        pager.setOnChapterBoundariesOutListener(new OnChapterBoundariesOutListener() {
             @Override
             public void onFirstPageOutEvent() {
                 onFirstPageOut();
@@ -38,50 +36,65 @@ public abstract class ViewPagerReader extends BaseReader {
                 onLastPageOut();
             }
         });
-        viewPager.setOnChapterSingleTapListener(new OnChapterSingleTapListener() {
+        pager.setOnChapterSingleTapListener(new OnChapterSingleTapListener() {
             @Override
             public void onCenterTap() {
-                activity.onCenterSingleTap();
+                getReaderActivity().onCenterSingleTap();
             }
 
             @Override
             public void onLeftSideTap() {
-                viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, transitions);
+                pager.setCurrentItem(pager.getCurrentItem() - 1, transitions);
             }
 
             @Override
             public void onRightSideTap() {
-                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, transitions);
+                pager.setCurrentItem(pager.getCurrentItem() + 1, transitions);
             }
         });
+
+        adapter = new ViewPagerReaderAdapter(getChildFragmentManager());
+        pager.setAdapter(adapter);
+        setPages();
+
+        transitionsSubscription = getReaderActivity().getPreferences().enableTransitions()
+                .asObservable()
+                .subscribe(value -> transitions = value);
     }
 
     @Override
-    public int getTotalPages() {
-        return adapter.getCount();
+    public void onDestroyView() {
+        transitionsSubscription.unsubscribe();
+        super.onDestroyView();
+    }
+
+    @Override
+    public void onPageListReady(List<Page> pages, int currentPage) {
+        this.pages = pages;
+        this.currentPage = currentPage;
+        if (isResumed()) {
+            setPages();
+        }
+    }
+
+    protected void setPages() {
+        if (pages != null) {
+            pager.clearOnPageChangeListeners();
+            adapter.setPages(pages);
+            setSelectedPage(currentPage);
+            updatePageNumber();
+            pager.setOnPageChangeListener(this::onPageChanged);
+        }
     }
 
     @Override
     public void setSelectedPage(int pageNumber) {
-        viewPager.setCurrentItem(getCurrentPageIndex(pageNumber), false);
+        pager.setCurrentItem(getPositionForPage(pageNumber), false);
     }
 
     @Override
     public boolean onImageTouch(MotionEvent motionEvent) {
-        return viewPager.onImageTouch(motionEvent);
-    }
-
-    @Override
-    public void onPageListReady(List<Page> pages) {
-        currentPosition = 0;
-        adapter = new ViewPagerReaderAdapter(activity.getSupportFragmentManager(), pages);
-        viewPager.setAdapter(adapter);
-    }
-
-    @Override
-    @CallSuper
-    public void destroy() {
-        transitionsSubscription.unsubscribe();
+        return pager.onImageTouch(motionEvent);
     }
 
     public abstract void onFirstPageOut();
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderAdapter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderAdapter.java
index 859a4e28f0..7c4e432dca 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderAdapter.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderAdapter.java
@@ -2,24 +2,23 @@ package eu.kanade.mangafeed.ui.reader.viewer.common;
 
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
 
 import java.util.List;
 
 import eu.kanade.mangafeed.data.source.model.Page;
-import eu.kanade.mangafeed.ui.base.adapter.SmartFragmentStatePagerAdapter;
 
-public class ViewPagerReaderAdapter extends SmartFragmentStatePagerAdapter {
+public class ViewPagerReaderAdapter extends FragmentStatePagerAdapter {
 
     private List<Page> pages;
 
-    public ViewPagerReaderAdapter(FragmentManager fragmentManager, List<Page> pages) {
+    public ViewPagerReaderAdapter(FragmentManager fragmentManager) {
         super(fragmentManager);
-        this.pages = pages;
     }
 
     @Override
     public int getCount() {
-        return pages.size();
+        return pages == null ? 0 : pages.size();
     }
 
     @Override
@@ -36,4 +35,9 @@ public class ViewPagerReaderAdapter extends SmartFragmentStatePagerAdapter {
         notifyDataSetChanged();
     }
 
+    @Override
+    public int getItemPosition(Object object) {
+        return POSITION_NONE;
+    }
+
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderFragment.java
index ff84b41c39..a3afb1287c 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderFragment.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/ViewPagerReaderFragment.java
@@ -24,6 +24,7 @@ import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.source.model.Page;
 import eu.kanade.mangafeed.ui.base.fragment.BaseFragment;
 import eu.kanade.mangafeed.ui.reader.ReaderActivity;
+import eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
 import rx.Observable;
 import rx.Subscription;
 import rx.android.schedulers.AndroidSchedulers;
@@ -38,7 +39,6 @@ public class ViewPagerReaderFragment extends BaseFragment {
     @Bind(R.id.progress_text) TextView progressText;
     @Bind(R.id.retry_button) Button retryButton;
 
-    private ReaderActivity activity;
     private Page page;
     private Subscription progressSubscription;
     private Subscription statusSubscription;
@@ -53,7 +53,7 @@ public class ViewPagerReaderFragment extends BaseFragment {
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.fragment_page, container, false);
         ButterKnife.bind(this, view);
-        activity = (ReaderActivity) getActivity();
+        ReaderActivity activity = (ReaderActivity) getActivity();
 
         if (activity.getReaderTheme() == ReaderActivity.BLACK_THEME) {
              progressText.setTextColor(ContextCompat.getColor(getContext(), R.color.light_grey));
@@ -65,7 +65,7 @@ public class ViewPagerReaderFragment extends BaseFragment {
         imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
         imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
         imageView.setOnTouchListener((v, motionEvent) ->
-                activity.getViewer().onImageTouch(motionEvent));
+                ((BaseReader) getParentFragment()).onImageTouch(motionEvent));
 
         retryButton.setOnTouchListener((v, event) -> {
             if (event.getAction() == MotionEvent.ACTION_UP) {
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalReader.java
index 4f57124c31..c825dc4a6c 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalReader.java
@@ -1,26 +1,19 @@
 package eu.kanade.mangafeed.ui.reader.viewer.horizontal;
 
-import eu.kanade.mangafeed.R;
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
-import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader;
 
 public abstract class HorizontalReader extends ViewPagerReader {
 
-    public HorizontalReader(ReaderActivity activity) {
-        super(activity);
-        activity.getLayoutInflater().inflate(R.layout.reader_horizontal, container);
-
-        viewPager = (ViewPagerInterface) container.findViewById(R.id.view_pager);
-        initializeViewPager();
-        ((HorizontalViewPager) viewPager).addOnPageChangeListener(new PageChangeListener());
-    }
-
-    private class PageChangeListener extends HorizontalViewPager.SimpleOnPageChangeListener {
-        @Override
-        public void onPageSelected(int position) {
-            onPageChanged(position);
-        }
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+        HorizontalViewPager pager = new HorizontalViewPager(getActivity());
+        initializePager(pager);
+        return pager;
     }
 
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalViewPager.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalViewPager.java
index a3c867f58a..938a878096 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalViewPager.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/HorizontalViewPager.java
@@ -10,6 +10,7 @@ import eu.kanade.mangafeed.ui.reader.viewer.common.OnChapterBoundariesOutListene
 import eu.kanade.mangafeed.ui.reader.viewer.common.OnChapterSingleTapListener;
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener;
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
+import rx.functions.Action1;
 
 public class HorizontalViewPager extends ViewPager implements ViewPagerInterface {
 
@@ -110,4 +111,14 @@ public class HorizontalViewPager extends ViewPager implements ViewPagerInterface
         return onChapterSingleTapListener;
     }
 
+    @Override
+    public void setOnPageChangeListener(Action1<Integer> function) {
+        addOnPageChangeListener(new SimpleOnPageChangeListener() {
+            @Override
+            public void onPageSelected(int position) {
+                function.call(position);
+            }
+        });
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java
index 0e5eaf2e30..fe5bfb1af6 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java
@@ -1,13 +1,7 @@
 package eu.kanade.mangafeed.ui.reader.viewer.horizontal;
 
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
-
 public class LeftToRightReader extends HorizontalReader {
 
-    public LeftToRightReader(ReaderActivity activity) {
-        super(activity);
-    }
-
     @Override
     public void onFirstPageOut() {
         requestPreviousChapter();
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java
index e63d983aa9..3f476a48e7 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java
@@ -5,25 +5,24 @@ import java.util.Collections;
 import java.util.List;
 
 import eu.kanade.mangafeed.data.source.model.Page;
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
 
 public class RightToLeftReader extends HorizontalReader {
 
-    public RightToLeftReader(ReaderActivity activity) {
-        super(activity);
-    }
-
     @Override
-    public void onPageListReady(List<Page> pages) {
+    public void onPageListReady(List<Page> pages, int currentPage) {
         ArrayList<Page> inversedPages = new ArrayList<>(pages);
         Collections.reverse(inversedPages);
-        super.onPageListReady(inversedPages);
-        viewPager.setCurrentItem(adapter.getCount() - 1, false);
+        super.onPageListReady(inversedPages, currentPage);
     }
 
     @Override
-    public int getCurrentPageIndex(int viewerPosition) {
-        return getTotalPages() - viewerPosition - 1;
+    public int getPageForPosition(int position) {
+        return (getTotalPages() - 1) - position;
+    }
+
+    @Override
+    public int getPositionForPage(int page) {
+        return (getTotalPages() - 1) - page;
     }
 
     @Override
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java
index 29c62879ad..4961506e3a 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java
@@ -1,19 +1,19 @@
 package eu.kanade.mangafeed.ui.reader.viewer.vertical;
 
-import eu.kanade.mangafeed.R;
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
-import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader;
 
 public class VerticalReader extends ViewPagerReader {
 
-    public VerticalReader(ReaderActivity activity) {
-        super(activity);
-        activity.getLayoutInflater().inflate(R.layout.reader_vertical, container);
-
-        viewPager = (ViewPagerInterface) container.findViewById(R.id.view_pager);
-        initializeViewPager();
-        ((VerticalViewPager) viewPager).addOnPageChangeListener(new PageChangeListener());
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+        VerticalViewPager pager = new VerticalViewPager(getActivity());
+        initializePager(pager);
+        return pager;
     }
 
     @Override
@@ -26,11 +26,4 @@ public class VerticalReader extends ViewPagerReader {
         requestNextChapter();
     }
 
-    private class PageChangeListener extends VerticalViewPagerImpl.SimpleOnPageChangeListener {
-        @Override
-        public void onPageSelected(int position) {
-            onPageChanged(position);
-        }
-    }
-
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalViewPager.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalViewPager.java
index b04d9c3ef3..1f704f8245 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalViewPager.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalViewPager.java
@@ -9,6 +9,7 @@ import eu.kanade.mangafeed.ui.reader.viewer.common.OnChapterBoundariesOutListene
 import eu.kanade.mangafeed.ui.reader.viewer.common.OnChapterSingleTapListener;
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener;
 import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
+import rx.functions.Action1;
 
 public class VerticalViewPager extends VerticalViewPagerImpl implements ViewPagerInterface {
 
@@ -109,7 +110,17 @@ public class VerticalViewPager extends VerticalViewPagerImpl implements ViewPage
         return onChapterSingleTapListener;
     }
 
-    private class VerticalViewPagerGestureListener extends ViewPagerGestureListener {
+    @Override
+    public void setOnPageChangeListener(Action1<Integer> function) {
+        addOnPageChangeListener(new SimpleOnPageChangeListener() {
+            @Override
+            public void onPageSelected(int position) {
+                function.call(position);
+            }
+        });
+    }
+
+    private static class VerticalViewPagerGestureListener extends ViewPagerGestureListener {
 
         public VerticalViewPagerGestureListener(ViewPagerInterface viewPager) {
             super(viewPager);
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java
index 4f5dee4b96..3c62434b37 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java
@@ -1,7 +1,9 @@
 package eu.kanade.mangafeed.ui.reader.viewer.webtoon;
 
-import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.ProgressBar;
 
 import com.davemorrissey.labs.subscaleview.ImageSource;
@@ -10,26 +12,40 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
 import java.util.ArrayList;
 import java.util.List;
 
+import butterknife.Bind;
+import butterknife.ButterKnife;
 import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.source.model.Page;
-import uk.co.ribot.easyadapter.BaseEasyRecyclerAdapter;
-import uk.co.ribot.easyadapter.ItemViewHolder;
-import uk.co.ribot.easyadapter.PositionInfo;
-import uk.co.ribot.easyadapter.annotations.LayoutId;
-import uk.co.ribot.easyadapter.annotations.ViewId;
 
-public class WebtoonAdapter extends BaseEasyRecyclerAdapter<Page> {
+public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHolder> {
 
-    List<Page> pages;
+    private List<Page> pages;
+    private WebtoonReader fragment;
+    private int maxBitmapSize;
+    private View.OnTouchListener listener;
 
-    public WebtoonAdapter(Context context) {
-        super(context, ImageViewHolder.class);
+    public WebtoonAdapter(WebtoonReader fragment) {
+        this.fragment = fragment;
         pages = new ArrayList<>();
+        maxBitmapSize = fragment.getReaderActivity().getMaxBitmapSize();
+        listener = (v, event) -> fragment.onImageTouch(event);
+    }
+
+    public Page getItem(int position) {
+        return pages.get(position);
     }
 
     @Override
-    public Page getItem(int position) {
-        return pages.get(position);
+    public ImageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        LayoutInflater inflater = fragment.getActivity().getLayoutInflater();
+        View v = inflater.inflate(R.layout.item_webtoon_reader, parent, false);
+        return new ImageHolder(v, maxBitmapSize, listener);
+    }
+
+    @Override
+    public void onBindViewHolder(ImageHolder holder, int position) {
+        final Page page = getItem(position);
+        holder.onSetValues(page);
     }
 
     @Override
@@ -37,33 +53,31 @@ public class WebtoonAdapter extends BaseEasyRecyclerAdapter<Page> {
         return pages.size();
     }
 
-    public void setPages(List<Page> pages) {
-        this.pages = pages;
-        notifyDataSetChanged();
-    }
-
     public void addPage(Page page) {
         pages.add(page);
-        notifyItemChanged(page.getPageNumber());
+        notifyItemInserted(page.getPageNumber());
     }
 
-    @LayoutId(R.layout.item_webtoon_reader)
-    static class ImageViewHolder extends ItemViewHolder<Page> {
+    public static class ImageHolder extends RecyclerView.ViewHolder {
 
-        @ViewId(R.id.page_image_view) SubsamplingScaleImageView imageView;
-        @ViewId(R.id.progress) ProgressBar progressBar;
+        @Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
+        @Bind(R.id.progress) ProgressBar progressBar;
 
-        public ImageViewHolder(View view) {
+        public ImageHolder(View view, int maxBitmapSize, View.OnTouchListener listener) {
             super(view);
+            ButterKnife.bind(this, view);
+
             imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
             imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
             imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
             imageView.setZoomEnabled(false);
             imageView.setPanEnabled(false);
+            imageView.setOnTouchListener(listener);
+            // TODO Using tiling here is annoying. RecyclerView isn't good at all for a webtoon reader
+//            imageView.setMaxDimensions(maxBitmapSize, maxBitmapSize);
         }
 
-        @Override
-        public void onSetValues(Page page, PositionInfo positionInfo) {
+        public void onSetValues(Page page) {
             if (page.getImagePath() != null) {
                 imageView.setVisibility(View.VISIBLE);
                 imageView.setImage(ImageSource.uri(page.getImagePath()).tilingDisabled());
@@ -72,7 +86,6 @@ public class WebtoonAdapter extends BaseEasyRecyclerAdapter<Page> {
                 imageView.setVisibility(View.GONE);
                 progressBar.setVisibility(View.VISIBLE);
             }
-
         }
     }
 }
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java
index 2cc591a8fd..3f9c3c2035 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java
@@ -1,51 +1,71 @@
 package eu.kanade.mangafeed.ui.reader.viewer.webtoon;
 
+import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
 
 import java.util.List;
 
 import eu.kanade.mangafeed.data.source.model.Page;
-import eu.kanade.mangafeed.ui.reader.ReaderActivity;
 import eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
 import rx.Subscription;
 import rx.android.schedulers.AndroidSchedulers;
 import rx.subjects.PublishSubject;
 
+import static android.view.GestureDetector.SimpleOnGestureListener;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public class WebtoonReader extends BaseReader {
 
-    private RecyclerView recycler;
-    private LinearLayoutManager layoutManager;
     private WebtoonAdapter adapter;
-    private List<Page> pages;
     private Subscription subscription;
+    private GestureDetector gestureDetector;
 
-    public WebtoonReader(ReaderActivity activity) {
-        super(activity);
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+        adapter = new WebtoonAdapter(this);
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
 
-        recycler = new RecyclerView(activity);
-        layoutManager = new LinearLayoutManager(activity);
+        RecyclerView recycler = new RecyclerView(getActivity());
+        recycler.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
         recycler.setLayoutManager(layoutManager);
-        adapter = new WebtoonAdapter(activity);
+        recycler.setItemAnimator(null);
         recycler.setAdapter(adapter);
-
         recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
             @Override
             public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                 super.onScrolled(recyclerView, dx, dy);
 
-                currentPosition = layoutManager.findFirstVisibleItemPosition();
+                currentPage = layoutManager.findLastVisibleItemPosition();
                 updatePageNumber();
             }
         });
 
-        container.addView(recycler);
+        gestureDetector = new GestureDetector(getActivity(), new SimpleOnGestureListener() {
+            @Override
+            public boolean onSingleTapConfirmed(MotionEvent e) {
+                getReaderActivity().onCenterSingleTap();
+                return true;
+            }
+        });
+
+        setPages();
+
+        return recycler;
     }
 
     @Override
-    public int getTotalPages() {
-        return pages.size();
+    public void onPause() {
+        if (subscription != null && !subscription.isUnsubscribed())
+            subscription.unsubscribe();
+        super.onPause();
     }
 
     @Override
@@ -55,14 +75,22 @@ public class WebtoonReader extends BaseReader {
     }
 
     @Override
-    public void onPageListReady(List<Page> pages) {
+    public void onPageListReady(List<Page> pages, int currentPage) {
         this.pages = pages;
-        observeStatus(0);
+        if (isResumed()) {
+            setPages();
+        }
+    }
+
+    private void setPages() {
+        if (pages != null) {
+            observeStatus(0);
+        }
     }
 
     @Override
     public boolean onImageTouch(MotionEvent motionEvent) {
-        return true;
+        return gestureDetector.onTouchEvent(motionEvent);
     }
 
     private void observeStatus(int position) {
@@ -99,9 +127,4 @@ public class WebtoonReader extends BaseReader {
         }
     }
 
-    @Override
-    public void destroy() {
-        if (subscription != null && !subscription.isUnsubscribed())
-            subscription.unsubscribe();
-    }
 }
diff --git a/app/src/main/res/layout/reader_horizontal.xml b/app/src/main/res/layout/reader_horizontal.xml
deleted file mode 100644
index ccf09fbb2a..0000000000
--- a/app/src/main/res/layout/reader_horizontal.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<eu.kanade.mangafeed.ui.reader.viewer.horizontal.HorizontalViewPager
-    android:id="@+id/view_pager"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    xmlns:android="http://schemas.android.com/apk/res/android">
-</eu.kanade.mangafeed.ui.reader.viewer.horizontal.HorizontalViewPager>
\ No newline at end of file
diff --git a/app/src/main/res/layout/reader_vertical.xml b/app/src/main/res/layout/reader_vertical.xml
deleted file mode 100644
index c9a8f85b40..0000000000
--- a/app/src/main/res/layout/reader_vertical.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<eu.kanade.mangafeed.ui.reader.viewer.vertical.VerticalViewPager
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/view_pager"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-</eu.kanade.mangafeed.ui.reader.viewer.vertical.VerticalViewPager>