Host readers inside a fragment (Avoids some leaks)

This commit is contained in:
inorichi 2016-01-04 01:31:15 +01:00
parent ddc188700c
commit 631ef65502
18 changed files with 248 additions and 211 deletions

View File

@ -11,9 +11,7 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.Surface; import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import java.util.List; import java.util.List;
@ -45,7 +43,6 @@ import rx.subscriptions.CompositeSubscription;
public class ReaderActivity extends BaseRxActivity<ReaderPresenter> { public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
@Bind(R.id.page_number) TextView pageNumber; @Bind(R.id.page_number) TextView pageNumber;
@Bind(R.id.reader) FrameLayout container;
@Bind(R.id.toolbar) Toolbar toolbar; @Bind(R.id.toolbar) Toolbar toolbar;
@Inject PreferencesHelper preferences; @Inject PreferencesHelper preferences;
@ -103,15 +100,14 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
@Override @Override
protected void onPause() { protected void onPause() {
if (viewer != null) if (viewer != null)
getPresenter().setCurrentPage(viewer.getCurrentPosition()); getPresenter().setCurrentPage(viewer.getCurrentPage());
super.onPause(); super.onPause();
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
subscriptions.unsubscribe(); subscriptions.unsubscribe();
if (viewer != null) viewer = null;
viewer.destroy();
super.onDestroy(); super.onDestroy();
} }
@ -126,13 +122,13 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
ToastUtil.showShort(this, R.string.page_list_error); ToastUtil.showShort(this, R.string.page_list_error);
} }
public void onChapterReady(List<Page> pages, Manga manga, Chapter chapter) { public void onChapterReady(List<Page> pages, Manga manga, Chapter chapter, int currentPage) {
if (viewer != null) if (viewer == null) {
viewer.destroy(); viewer = createViewer(manga);
viewer = createViewer(manga); getSupportFragmentManager().beginTransaction().replace(R.id.reader, viewer).commit();
viewer.onPageListReady(pages); }
viewer.updatePageNumber(); viewer.onPageListReady(pages, currentPage);
readerMenu.onChapterReady(pages.size(), manga, chapter); readerMenu.onChapterReady(pages.size(), manga, chapter, currentPage);
} }
private BaseReader createViewer(Manga manga) { private BaseReader createViewer(Manga manga) {
@ -140,13 +136,13 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
switch (mangaViewer) { switch (mangaViewer) {
case LEFT_TO_RIGHT: default: case LEFT_TO_RIGHT: default:
return new LeftToRightReader(this); return new LeftToRightReader();
case RIGHT_TO_LEFT: case RIGHT_TO_LEFT:
return new RightToLeftReader(this); return new RightToLeftReader();
case VERTICAL: case VERTICAL:
return new VerticalReader(this); return new VerticalReader();
case WEBTOON: case WEBTOON:
return new WebtoonReader(this); return new WebtoonReader();
} }
} }
@ -279,10 +275,6 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
return readerTheme; return readerTheme;
} }
public ViewGroup getContainer() {
return container;
}
public PreferencesHelper getPreferences() { public PreferencesHelper getPreferences() {
return preferences; return preferences;
} }

View File

@ -106,7 +106,7 @@ public class ReaderMenu {
showing = false; 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) { if (manga.viewer == ReaderActivity.RIGHT_TO_LEFT && !inverted) {
// Invert the seekbar and textview fields for the right to left reader // Invert the seekbar and textview fields for the right to left reader
seekBar.setRotation(180); seekBar.setRotation(180);
@ -119,7 +119,8 @@ public class ReaderMenu {
// Set initial values // Set initial values
totalPages.setText("" + numPages); totalPages.setText("" + numPages);
currentPage.setText("" + (chapter.last_page_read + 1)); currentPage.setText("" + (currentPageIndex + 1));
seekBar.setProgress(currentPageIndex);
seekBar.setMax(numPages - 1); seekBar.setMax(numPages - 1);
activity.setToolbarTitle(manga.title); activity.setToolbarTitle(manga.title);

View File

@ -90,11 +90,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
start(GET_PAGE_IMAGES); start(GET_PAGE_IMAGES);
start(RETRY_IMAGES); start(RETRY_IMAGES);
}), }),
(view, pages) -> { (view, pages) -> view.onChapterReady(pages, manga, chapter, currentPage),
view.onChapterReady(pages, manga, chapter);
if (currentPage != 0)
view.setSelectedPage(currentPage);
},
(view, error) -> view.onChapterError()); (view, error) -> view.onChapterError());
registerForStickyEvents(); registerForStickyEvents();

View File

@ -1,71 +1,72 @@
package eu.kanade.mangafeed.ui.reader.viewer.base; package eu.kanade.mangafeed.ui.reader.viewer.base;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewGroup;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page; 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.ReaderActivity;
import eu.kanade.mangafeed.ui.reader.ReaderPresenter; import eu.kanade.mangafeed.ui.reader.ReaderPresenter;
import eu.kanade.mangafeed.util.ToastUtil; import eu.kanade.mangafeed.util.ToastUtil;
public abstract class BaseReader { public abstract class BaseReader extends BaseFragment {
protected ReaderActivity activity; protected int currentPage;
protected ReaderPresenter presenter; protected List<Page> pages;
protected ViewGroup container;
protected int currentPosition;
public BaseReader(ReaderActivity activity) {
this.activity = activity;
this.container = activity.getContainer();
this.presenter = activity.getPresenter();
}
public void updatePageNumber() { 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, public int getCurrentPage() {
// where the current page is the inverse of the position return currentPage;
public int getCurrentPageIndex(int viewerPosition) {
return viewerPosition;
} }
public int getCurrentPosition() { public int getPageForPosition(int position) {
return getCurrentPageIndex(currentPosition); return position;
}
public int getPositionForPage(int page) {
return page;
} }
public void requestNextChapter() { public void requestNextChapter() {
ReaderPresenter presenter = getReaderActivity().getPresenter();
if (presenter.hasNextChapter()) { if (presenter.hasNextChapter()) {
presenter.setCurrentPage(getCurrentPosition()); presenter.setCurrentPage(getCurrentPage());
presenter.loadNextChapter(); presenter.loadNextChapter();
} else { } else {
ToastUtil.showShort(activity, R.string.no_next_chapter); ToastUtil.showShort(getActivity(), R.string.no_next_chapter);
} }
} }
public void requestPreviousChapter() { public void requestPreviousChapter() {
ReaderPresenter presenter = getReaderActivity().getPresenter();
if (presenter.hasPreviousChapter()) { if (presenter.hasPreviousChapter()) {
presenter.setCurrentPage(getCurrentPosition()); presenter.setCurrentPage(getCurrentPage());
presenter.loadPreviousChapter(); presenter.loadPreviousChapter();
} else { } else {
ToastUtil.showShort(activity, R.string.no_previous_chapter); ToastUtil.showShort(getActivity(), R.string.no_previous_chapter);
} }
} }
public void onPageChanged(int position) { public void onPageChanged(int position) {
currentPosition = position; currentPage = getPageForPosition(position);
updatePageNumber(); 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 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 abstract boolean onImageTouch(MotionEvent motionEvent);
public ReaderActivity getReaderActivity() {
return (ReaderActivity) getActivity();
}
} }

View File

@ -2,9 +2,15 @@ package eu.kanade.mangafeed.ui.reader.viewer.common;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewGroup;
import rx.functions.Action1;
public interface ViewPagerInterface { public interface ViewPagerInterface {
void setId(int id);
void setLayoutParams(ViewGroup.LayoutParams layoutParams);
void setOffscreenPageLimit(int limit); void setOffscreenPageLimit(int limit);
int getCurrentItem(); int getCurrentItem();
@ -24,4 +30,6 @@ public interface ViewPagerInterface {
OnChapterBoundariesOutListener getChapterBoundariesListener(); OnChapterBoundariesOutListener getChapterBoundariesListener();
OnChapterSingleTapListener getChapterSingleTapListener(); OnChapterSingleTapListener getChapterSingleTapListener();
void setOnPageChangeListener(Action1<Integer> onPageChanged);
void clearOnPageChangeListeners();
} }

View File

@ -1,33 +1,31 @@
package eu.kanade.mangafeed.ui.reader.viewer.common; package eu.kanade.mangafeed.ui.reader.viewer.common;
import android.support.annotation.CallSuper;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewGroup;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page; 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 eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
import rx.Subscription; import rx.Subscription;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public abstract class ViewPagerReader extends BaseReader { public abstract class ViewPagerReader extends BaseReader {
protected ViewPagerReaderAdapter adapter; protected ViewPagerReaderAdapter adapter;
protected ViewPagerInterface viewPager; protected ViewPagerInterface pager;
protected boolean transitions; protected boolean transitions;
protected Subscription transitionsSubscription; protected Subscription transitionsSubscription;
public ViewPagerReader(ReaderActivity activity) { protected void initializePager(ViewPagerInterface pager) {
super(activity); this.pager = pager;
pager.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
transitionsSubscription = activity.getPreferences().enableTransitions().asObservable() pager.setOffscreenPageLimit(2);
.subscribe(value -> transitions = value); pager.setId(R.id.view_pager);
} pager.setOnChapterBoundariesOutListener(new OnChapterBoundariesOutListener() {
protected void initializeViewPager() {
viewPager.setOffscreenPageLimit(2);
viewPager.setOnChapterBoundariesOutListener(new OnChapterBoundariesOutListener() {
@Override @Override
public void onFirstPageOutEvent() { public void onFirstPageOutEvent() {
onFirstPageOut(); onFirstPageOut();
@ -38,50 +36,65 @@ public abstract class ViewPagerReader extends BaseReader {
onLastPageOut(); onLastPageOut();
} }
}); });
viewPager.setOnChapterSingleTapListener(new OnChapterSingleTapListener() { pager.setOnChapterSingleTapListener(new OnChapterSingleTapListener() {
@Override @Override
public void onCenterTap() { public void onCenterTap() {
activity.onCenterSingleTap(); getReaderActivity().onCenterSingleTap();
} }
@Override @Override
public void onLeftSideTap() { public void onLeftSideTap() {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, transitions); pager.setCurrentItem(pager.getCurrentItem() - 1, transitions);
} }
@Override @Override
public void onRightSideTap() { 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 @Override
public int getTotalPages() { public void onDestroyView() {
return adapter.getCount(); 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 @Override
public void setSelectedPage(int pageNumber) { public void setSelectedPage(int pageNumber) {
viewPager.setCurrentItem(getCurrentPageIndex(pageNumber), false); pager.setCurrentItem(getPositionForPage(pageNumber), false);
} }
@Override @Override
public boolean onImageTouch(MotionEvent motionEvent) { public boolean onImageTouch(MotionEvent motionEvent) {
return viewPager.onImageTouch(motionEvent); return pager.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();
} }
public abstract void onFirstPageOut(); public abstract void onFirstPageOut();

View File

@ -2,24 +2,23 @@ package eu.kanade.mangafeed.ui.reader.viewer.common;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.data.source.model.Page; 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; private List<Page> pages;
public ViewPagerReaderAdapter(FragmentManager fragmentManager, List<Page> pages) { public ViewPagerReaderAdapter(FragmentManager fragmentManager) {
super(fragmentManager); super(fragmentManager);
this.pages = pages;
} }
@Override @Override
public int getCount() { public int getCount() {
return pages.size(); return pages == null ? 0 : pages.size();
} }
@Override @Override
@ -36,4 +35,9 @@ public class ViewPagerReaderAdapter extends SmartFragmentStatePagerAdapter {
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
} }

View File

@ -24,6 +24,7 @@ import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.ui.base.fragment.BaseFragment; import eu.kanade.mangafeed.ui.base.fragment.BaseFragment;
import eu.kanade.mangafeed.ui.reader.ReaderActivity; import eu.kanade.mangafeed.ui.reader.ReaderActivity;
import eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
import rx.Observable; import rx.Observable;
import rx.Subscription; import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
@ -38,7 +39,6 @@ public class ViewPagerReaderFragment extends BaseFragment {
@Bind(R.id.progress_text) TextView progressText; @Bind(R.id.progress_text) TextView progressText;
@Bind(R.id.retry_button) Button retryButton; @Bind(R.id.retry_button) Button retryButton;
private ReaderActivity activity;
private Page page; private Page page;
private Subscription progressSubscription; private Subscription progressSubscription;
private Subscription statusSubscription; private Subscription statusSubscription;
@ -53,7 +53,7 @@ public class ViewPagerReaderFragment extends BaseFragment {
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page, container, false); View view = inflater.inflate(R.layout.fragment_page, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
activity = (ReaderActivity) getActivity(); ReaderActivity activity = (ReaderActivity) getActivity();
if (activity.getReaderTheme() == ReaderActivity.BLACK_THEME) { if (activity.getReaderTheme() == ReaderActivity.BLACK_THEME) {
progressText.setTextColor(ContextCompat.getColor(getContext(), R.color.light_grey)); 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.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE); imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setOnTouchListener((v, motionEvent) -> imageView.setOnTouchListener((v, motionEvent) ->
activity.getViewer().onImageTouch(motionEvent)); ((BaseReader) getParentFragment()).onImageTouch(motionEvent));
retryButton.setOnTouchListener((v, event) -> { retryButton.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {

View File

@ -1,26 +1,19 @@
package eu.kanade.mangafeed.ui.reader.viewer.horizontal; package eu.kanade.mangafeed.ui.reader.viewer.horizontal;
import eu.kanade.mangafeed.R; import android.os.Bundle;
import eu.kanade.mangafeed.ui.reader.ReaderActivity; import android.view.LayoutInflater;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface; import android.view.View;
import android.view.ViewGroup;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader;
public abstract class HorizontalReader extends ViewPagerReader { public abstract class HorizontalReader extends ViewPagerReader {
public HorizontalReader(ReaderActivity activity) { @Override
super(activity); public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
activity.getLayoutInflater().inflate(R.layout.reader_horizontal, container); HorizontalViewPager pager = new HorizontalViewPager(getActivity());
initializePager(pager);
viewPager = (ViewPagerInterface) container.findViewById(R.id.view_pager); return pager;
initializeViewPager();
((HorizontalViewPager) viewPager).addOnPageChangeListener(new PageChangeListener());
}
private class PageChangeListener extends HorizontalViewPager.SimpleOnPageChangeListener {
@Override
public void onPageSelected(int position) {
onPageChanged(position);
}
} }
} }

View File

@ -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.OnChapterSingleTapListener;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
import rx.functions.Action1;
public class HorizontalViewPager extends ViewPager implements ViewPagerInterface { public class HorizontalViewPager extends ViewPager implements ViewPagerInterface {
@ -110,4 +111,14 @@ public class HorizontalViewPager extends ViewPager implements ViewPagerInterface
return onChapterSingleTapListener; return onChapterSingleTapListener;
} }
@Override
public void setOnPageChangeListener(Action1<Integer> function) {
addOnPageChangeListener(new SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
function.call(position);
}
});
}
} }

View File

@ -1,13 +1,7 @@
package eu.kanade.mangafeed.ui.reader.viewer.horizontal; package eu.kanade.mangafeed.ui.reader.viewer.horizontal;
import eu.kanade.mangafeed.ui.reader.ReaderActivity;
public class LeftToRightReader extends HorizontalReader { public class LeftToRightReader extends HorizontalReader {
public LeftToRightReader(ReaderActivity activity) {
super(activity);
}
@Override @Override
public void onFirstPageOut() { public void onFirstPageOut() {
requestPreviousChapter(); requestPreviousChapter();

View File

@ -5,25 +5,24 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.ui.reader.ReaderActivity;
public class RightToLeftReader extends HorizontalReader { public class RightToLeftReader extends HorizontalReader {
public RightToLeftReader(ReaderActivity activity) {
super(activity);
}
@Override @Override
public void onPageListReady(List<Page> pages) { public void onPageListReady(List<Page> pages, int currentPage) {
ArrayList<Page> inversedPages = new ArrayList<>(pages); ArrayList<Page> inversedPages = new ArrayList<>(pages);
Collections.reverse(inversedPages); Collections.reverse(inversedPages);
super.onPageListReady(inversedPages); super.onPageListReady(inversedPages, currentPage);
viewPager.setCurrentItem(adapter.getCount() - 1, false);
} }
@Override @Override
public int getCurrentPageIndex(int viewerPosition) { public int getPageForPosition(int position) {
return getTotalPages() - viewerPosition - 1; return (getTotalPages() - 1) - position;
}
@Override
public int getPositionForPage(int page) {
return (getTotalPages() - 1) - page;
} }
@Override @Override

View File

@ -1,19 +1,19 @@
package eu.kanade.mangafeed.ui.reader.viewer.vertical; package eu.kanade.mangafeed.ui.reader.viewer.vertical;
import eu.kanade.mangafeed.R; import android.os.Bundle;
import eu.kanade.mangafeed.ui.reader.ReaderActivity; import android.view.LayoutInflater;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface; import android.view.View;
import android.view.ViewGroup;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerReader;
public class VerticalReader extends ViewPagerReader { public class VerticalReader extends ViewPagerReader {
public VerticalReader(ReaderActivity activity) { @Override
super(activity); public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
activity.getLayoutInflater().inflate(R.layout.reader_vertical, container); VerticalViewPager pager = new VerticalViewPager(getActivity());
initializePager(pager);
viewPager = (ViewPagerInterface) container.findViewById(R.id.view_pager); return pager;
initializeViewPager();
((VerticalViewPager) viewPager).addOnPageChangeListener(new PageChangeListener());
} }
@Override @Override
@ -26,11 +26,4 @@ public class VerticalReader extends ViewPagerReader {
requestNextChapter(); requestNextChapter();
} }
private class PageChangeListener extends VerticalViewPagerImpl.SimpleOnPageChangeListener {
@Override
public void onPageSelected(int position) {
onPageChanged(position);
}
}
} }

View File

@ -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.OnChapterSingleTapListener;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerGestureListener;
import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface; import eu.kanade.mangafeed.ui.reader.viewer.common.ViewPagerInterface;
import rx.functions.Action1;
public class VerticalViewPager extends VerticalViewPagerImpl implements ViewPagerInterface { public class VerticalViewPager extends VerticalViewPagerImpl implements ViewPagerInterface {
@ -109,7 +110,17 @@ public class VerticalViewPager extends VerticalViewPagerImpl implements ViewPage
return onChapterSingleTapListener; 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) { public VerticalViewPagerGestureListener(ViewPagerInterface viewPager) {
super(viewPager); super(viewPager);

View File

@ -1,7 +1,9 @@
package eu.kanade.mangafeed.ui.reader.viewer.webtoon; 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.View;
import android.view.ViewGroup;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.davemorrissey.labs.subscaleview.ImageSource; import com.davemorrissey.labs.subscaleview.ImageSource;
@ -10,26 +12,40 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page; 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) { public WebtoonAdapter(WebtoonReader fragment) {
super(context, ImageViewHolder.class); this.fragment = fragment;
pages = new ArrayList<>(); pages = new ArrayList<>();
maxBitmapSize = fragment.getReaderActivity().getMaxBitmapSize();
listener = (v, event) -> fragment.onImageTouch(event);
}
public Page getItem(int position) {
return pages.get(position);
} }
@Override @Override
public Page getItem(int position) { public ImageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return pages.get(position); 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 @Override
@ -37,33 +53,31 @@ public class WebtoonAdapter extends BaseEasyRecyclerAdapter<Page> {
return pages.size(); return pages.size();
} }
public void setPages(List<Page> pages) {
this.pages = pages;
notifyDataSetChanged();
}
public void addPage(Page page) { public void addPage(Page page) {
pages.add(page); pages.add(page);
notifyItemChanged(page.getPageNumber()); notifyItemInserted(page.getPageNumber());
} }
@LayoutId(R.layout.item_webtoon_reader) public static class ImageHolder extends RecyclerView.ViewHolder {
static class ImageViewHolder extends ItemViewHolder<Page> {
@ViewId(R.id.page_image_view) SubsamplingScaleImageView imageView; @Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
@ViewId(R.id.progress) ProgressBar progressBar; @Bind(R.id.progress) ProgressBar progressBar;
public ImageViewHolder(View view) { public ImageHolder(View view, int maxBitmapSize, View.OnTouchListener listener) {
super(view); super(view);
ButterKnife.bind(this, view);
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_CENTER_INSIDE); imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setZoomEnabled(false); imageView.setZoomEnabled(false);
imageView.setPanEnabled(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) {
public void onSetValues(Page page, PositionInfo positionInfo) {
if (page.getImagePath() != null) { if (page.getImagePath() != null) {
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
imageView.setImage(ImageSource.uri(page.getImagePath()).tilingDisabled()); imageView.setImage(ImageSource.uri(page.getImagePath()).tilingDisabled());
@ -72,7 +86,6 @@ public class WebtoonAdapter extends BaseEasyRecyclerAdapter<Page> {
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
} }
} }
} }
} }

View File

@ -1,51 +1,71 @@
package eu.kanade.mangafeed.ui.reader.viewer.webtoon; 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.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.data.source.model.Page; 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 eu.kanade.mangafeed.ui.reader.viewer.base.BaseReader;
import rx.Subscription; import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
import rx.subjects.PublishSubject; import rx.subjects.PublishSubject;
import static android.view.GestureDetector.SimpleOnGestureListener;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public class WebtoonReader extends BaseReader { public class WebtoonReader extends BaseReader {
private RecyclerView recycler;
private LinearLayoutManager layoutManager;
private WebtoonAdapter adapter; private WebtoonAdapter adapter;
private List<Page> pages;
private Subscription subscription; private Subscription subscription;
private GestureDetector gestureDetector;
public WebtoonReader(ReaderActivity activity) { @Nullable
super(activity); @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
adapter = new WebtoonAdapter(this);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recycler = new RecyclerView(activity); RecyclerView recycler = new RecyclerView(getActivity());
layoutManager = new LinearLayoutManager(activity); recycler.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
recycler.setLayoutManager(layoutManager); recycler.setLayoutManager(layoutManager);
adapter = new WebtoonAdapter(activity); recycler.setItemAnimator(null);
recycler.setAdapter(adapter); recycler.setAdapter(adapter);
recycler.addOnScrollListener(new RecyclerView.OnScrollListener() { recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) { public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy); super.onScrolled(recyclerView, dx, dy);
currentPosition = layoutManager.findFirstVisibleItemPosition(); currentPage = layoutManager.findLastVisibleItemPosition();
updatePageNumber(); updatePageNumber();
} }
}); });
container.addView(recycler); gestureDetector = new GestureDetector(getActivity(), new SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
getReaderActivity().onCenterSingleTap();
return true;
}
});
setPages();
return recycler;
} }
@Override @Override
public int getTotalPages() { public void onPause() {
return pages.size(); if (subscription != null && !subscription.isUnsubscribed())
subscription.unsubscribe();
super.onPause();
} }
@Override @Override
@ -55,14 +75,22 @@ public class WebtoonReader extends BaseReader {
} }
@Override @Override
public void onPageListReady(List<Page> pages) { public void onPageListReady(List<Page> pages, int currentPage) {
this.pages = pages; this.pages = pages;
observeStatus(0); if (isResumed()) {
setPages();
}
}
private void setPages() {
if (pages != null) {
observeStatus(0);
}
} }
@Override @Override
public boolean onImageTouch(MotionEvent motionEvent) { public boolean onImageTouch(MotionEvent motionEvent) {
return true; return gestureDetector.onTouchEvent(motionEvent);
} }
private void observeStatus(int position) { 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();
}
} }

View File

@ -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>

View File

@ -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>