Browse Source

Add buttons to open next/previous chapter in the reader. Try entire app with hardware acceleration

inorichi 10 năm trước cách đây
mục cha
commit
d0089e3f5e
26 tập tin đã thay đổi với 159 bổ sung64 xóa
  1. 2 2
      app/src/main/AndroidManifest.xml
  2. 31 0
      app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java
  3. 37 0
      app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java
  4. 32 21
      app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
  5. 0 24
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java
  6. 6 4
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java
  7. 2 2
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java
  8. 2 2
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java
  9. 2 2
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java
  10. 7 0
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java
  11. 14 6
      app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java
  12. 2 1
      app/src/main/res/anim/fade_in.xml
  13. BIN
      app/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png
  14. BIN
      app/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png
  15. BIN
      app/src/main/res/drawable-ldpi/ic_skip_next_white_24dp.png
  16. BIN
      app/src/main/res/drawable-ldpi/ic_skip_previous_white_24dp.png
  17. BIN
      app/src/main/res/drawable-mdpi/ic_skip_next_white_24dp.png
  18. BIN
      app/src/main/res/drawable-mdpi/ic_skip_previous_white_24dp.png
  19. BIN
      app/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png
  20. BIN
      app/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png
  21. BIN
      app/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png
  22. BIN
      app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png
  23. BIN
      app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_24dp.png
  24. BIN
      app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_24dp.png
  25. 19 0
      app/src/main/res/menu/reader.xml
  26. 3 0
      app/src/main/res/values/strings.xml

+ 2 - 2
app/src/main/AndroidManifest.xml

@@ -12,6 +12,7 @@
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
+        android:hardwareAccelerated="true"
         android:theme="@style/AppTheme" >
         <activity
             android:name=".ui.main.MainActivity">
@@ -27,8 +28,7 @@
         </activity>
         <activity
             android:name=".ui.reader.ReaderActivity"
-            android:parentActivityName=".ui.manga.MangaActivity"
-            android:hardwareAccelerated="true">
+            android:parentActivityName=".ui.manga.MangaActivity">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value=".ui.manga.MangaActivity" />

+ 31 - 0
app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java

@@ -9,6 +9,8 @@ import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.Surface;
 import android.view.View;
 import android.view.WindowManager;
@@ -111,6 +113,16 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
         super.onDestroy();
     }
 
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        return readerMenu.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        return readerMenu.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
+    }
+
     @Override
     protected void onSaveInstanceState(@NonNull Bundle outState) {
         Icepick.saveInstanceState(readerMenu, outState);
@@ -131,6 +143,10 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
         readerMenu.onChapterReady(pages.size(), manga, chapter, currentPage);
     }
 
+    public void onAdjacentChapters(Chapter previous, Chapter next) {
+        readerMenu.onAdjacentChapters(previous, next);
+    }
+
     private BaseReader createViewer(Manga manga) {
         int mangaViewer = manga.viewer == 0 ? preferences.getDefaultViewer() : manga.viewer;
 
@@ -160,6 +176,21 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
         readerMenu.toggle();
     }
 
+    public void requestNextChapter() {
+        getPresenter().setCurrentPage(viewer != null ? viewer.getCurrentPage() : 0);
+        if (!getPresenter().loadNextChapter()) {
+            ToastUtil.showShort(this, R.string.no_next_chapter);
+        }
+
+    }
+
+    public void requestPreviousChapter() {
+        getPresenter().setCurrentPage(viewer != null ? viewer.getCurrentPage() : 0);
+        if (!getPresenter().loadPreviousChapter()) {
+            ToastUtil.showShort(this, R.string.no_previous_chapter);
+        }
+    }
+
     private void initializeSettings() {
         subscriptions.add(preferences.showPageNumber()
                 .asObservable()

+ 37 - 0
app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java

@@ -5,6 +5,8 @@ import android.content.Context;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.widget.Toolbar;
 import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
@@ -42,6 +44,11 @@ public class ReaderMenu {
     @Bind(R.id.reader_extra_settings) ImageButton extraSettings;
     @Bind(R.id.reader_brightness) ImageButton brightnessSettings;
 
+    private MenuItem nextChapterBtn;
+    private MenuItem prevChapterBtn;
+    private Chapter prevChapter;
+    private Chapter nextChapter;
+
     private ReaderActivity activity;
     private PreferencesHelper preferences;
 
@@ -106,6 +113,25 @@ public class ReaderMenu {
         showing = false;
     }
 
+    public boolean onCreateOptionsMenu(Menu menu) {
+        activity.getMenuInflater().inflate(R.menu.reader, menu);
+        nextChapterBtn = menu.findItem(R.id.action_next_chapter);
+        prevChapterBtn = menu.findItem(R.id.action_previous_chapter);
+        setAdjacentChaptersVisibility();
+        return true;
+    }
+
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item == prevChapterBtn) {
+            activity.requestPreviousChapter();
+        } else if (item == nextChapterBtn) {
+            activity.requestNextChapter();
+        } else {
+            return false;
+        }
+        return true;
+    }
+
     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
@@ -136,6 +162,17 @@ public class ReaderMenu {
         seekBar.setProgress(pageIndex);
     }
 
+    public void onAdjacentChapters(Chapter previous, Chapter next) {
+        prevChapter = previous;
+        nextChapter = next;
+        setAdjacentChaptersVisibility();
+    }
+
+    private void setAdjacentChaptersVisibility() {
+        if (prevChapterBtn != null) prevChapterBtn.setVisible(prevChapter != null);
+        if (nextChapterBtn != null) nextChapterBtn.setVisible(nextChapter != null);
+    }
+
     private void initializeOptions() {
         // Orientation changes
         add(preferences.lockOrientation().asObservable()

+ 32 - 21
app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java

@@ -2,6 +2,7 @@ package eu.kanade.mangafeed.ui.reader;
 
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.util.Pair;
 
 import java.io.File;
 import java.util.List;
@@ -53,8 +54,9 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
 
     private static final int GET_PAGE_LIST = 1;
     private static final int GET_PAGE_IMAGES = 2;
-    private static final int RETRY_IMAGES = 3;
-    private static final int PRELOAD_NEXT_CHAPTER = 4;
+    private static final int GET_ADJACENT_CHAPTERS = 3;
+    private static final int RETRY_IMAGES = 4;
+    private static final int PRELOAD_NEXT_CHAPTER = 5;
 
     @Override
     protected void onCreate(Bundle savedState) {
@@ -71,12 +73,16 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
                 (view, pages) -> {},
                 (view, error) -> Timber.e("An error occurred while preloading a chapter"));
 
-        restartableReplay(GET_PAGE_IMAGES,
-                () -> getPageImagesObservable()
-                        .doOnCompleted(this::preloadNextChapter),
+        restartableLatestCache(GET_PAGE_IMAGES,
+                this::getPageImagesObservable,
                 (view, page) -> {},
                 (view, error) -> Timber.e("An error occurred while downloading an image"));
 
+        restartableLatestCache(GET_ADJACENT_CHAPTERS,
+                this::getAdjacentChaptersObservable,
+                (view, pair) -> view.onAdjacentChapters(pair.first, pair.second),
+                (view, error) -> Timber.e("An error occurred while getting adjacent chapters"));
+
         restartableLatestCache(RETRY_IMAGES,
                 this::getRetryPageObservable,
                 (view, page) -> {},
@@ -86,7 +92,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
                 () -> getPageListObservable()
                         .doOnNext(pages -> pageList = pages)
                         .doOnCompleted(() -> {
-                            getAdjacentChapters();
+                            start(GET_ADJACENT_CHAPTERS);
                             start(GET_PAGE_IMAGES);
                             start(RETRY_IMAGES);
                         }),
@@ -117,6 +123,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
 
         // These are started by GET_PAGE_LIST, so we don't let them restart itselves
         stop(GET_PAGE_IMAGES);
+        stop(GET_ADJACENT_CHAPTERS);
         stop(RETRY_IMAGES);
         stop(PRELOAD_NEXT_CHAPTER);
     }
@@ -153,9 +160,19 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
             pageObservable = Observable.from(pageList)
                     .flatMap(page -> downloadManager.getDownloadedImage(page, chapterDir));
         }
-        return Observable.defer(() -> pageObservable)
-                .subscribeOn(Schedulers.io())
-                .onBackpressureBuffer()
+        return pageObservable.subscribeOn(Schedulers.io())
+                .doOnCompleted(this::preloadNextChapter);
+    }
+
+    private Observable<Pair<Chapter, Chapter>> getAdjacentChaptersObservable() {
+        return Observable.zip(
+                db.getPreviousChapter(chapter).createObservable().take(1),
+                db.getNextChapter(chapter).createObservable().take(1),
+                Pair::create)
+                .doOnNext(pair -> {
+                    previousChapter = pair.first;
+                    nextChapter = pair.second;
+                })
                 .observeOn(AndroidSchedulers.mainThread());
     }
 
@@ -275,28 +292,22 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
         this.currentPage = currentPage;
     }
 
-    private void getAdjacentChapters() {
-        add(db.getNextChapter(chapter).createObservable()
-                .take(1)
-                .subscribe(result -> nextChapter = result));
-
-        add(db.getPreviousChapter(chapter).createObservable()
-                .take(1)
-                .subscribe(result -> previousChapter = result));
-    }
-
-    public void loadNextChapter() {
+    public boolean loadNextChapter() {
         if (hasNextChapter()) {
             onChapterLeft();
             loadChapter(nextChapter);
+            return true;
         }
+        return false;
     }
 
-    public void loadPreviousChapter() {
+    public boolean loadPreviousChapter() {
         if (hasPreviousChapter()) {
             onChapterLeft();
             loadChapter(previousChapter);
+            return true;
         }
+        return false;
     }
 
     public boolean hasNextChapter() {

+ 0 - 24
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java

@@ -4,12 +4,9 @@ import android.view.MotionEvent;
 
 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 extends BaseFragment {
 
@@ -32,27 +29,6 @@ public abstract class BaseReader extends BaseFragment {
         return page;
     }
 
-    public void requestNextChapter() {
-        ReaderPresenter presenter = getReaderActivity().getPresenter();
-        if (presenter.hasNextChapter()) {
-            presenter.setCurrentPage(getCurrentPage());
-            presenter.loadNextChapter();
-        } else {
-            ToastUtil.showShort(getActivity(), R.string.no_next_chapter);
-        }
-
-    }
-
-    public void requestPreviousChapter() {
-        ReaderPresenter presenter = getReaderActivity().getPresenter();
-        if (presenter.hasPreviousChapter()) {
-            presenter.setCurrentPage(getCurrentPage());
-            presenter.loadPreviousChapter();
-        } else {
-            ToastUtil.showShort(getActivity(), R.string.no_previous_chapter);
-        }
-    }
-
     public void onPageChanged(int position) {
         currentPage = getPageForPosition(position);
         updatePageNumber();

+ 6 - 4
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java

@@ -70,10 +70,12 @@ public abstract class PagerReader extends BaseReader {
 
     @Override
     public void onPageListReady(List<Page> pages, int currentPage) {
-        this.pages = pages;
-        this.currentPage = currentPage;
-        if (isResumed()) {
-            setPages();
+        if (this.pages != pages) {
+            this.pages = pages;
+            this.currentPage = currentPage;
+            if (isResumed()) {
+                setPages();
+            }
         }
     }
 

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java

@@ -4,12 +4,12 @@ public class LeftToRightReader extends HorizontalReader {
 
     @Override
     public void onFirstPageOut() {
-        requestPreviousChapter();
+        getReaderActivity().requestPreviousChapter();
     }
 
     @Override
     public void onLastPageOut() {
-        requestNextChapter();
+        getReaderActivity().requestNextChapter();
     }
 
 }

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java

@@ -27,12 +27,12 @@ public class RightToLeftReader extends HorizontalReader {
 
     @Override
     public void onFirstPageOut() {
-        requestNextChapter();
+        getReaderActivity().requestNextChapter();
     }
 
     @Override
     public void onLastPageOut() {
-        requestPreviousChapter();
+        getReaderActivity().requestPreviousChapter();
     }
 
 }

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java

@@ -18,12 +18,12 @@ public class VerticalReader extends PagerReader {
 
     @Override
     public void onFirstPageOut() {
-        requestPreviousChapter();
+        getReaderActivity().requestPreviousChapter();
     }
 
     @Override
     public void onLastPageOut() {
-        requestNextChapter();
+        getReaderActivity().requestNextChapter();
     }
 
 }

+ 7 - 0
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java

@@ -58,6 +58,13 @@ public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHol
         notifyItemInserted(page.getPageNumber());
     }
 
+    public void clear() {
+        if (pages != null) {
+            pages.clear();
+            notifyDataSetChanged();
+        }
+    }
+
     public static class ImageHolder extends RecyclerView.ViewHolder {
 
         @Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;

+ 14 - 6
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonReader.java

@@ -73,9 +73,13 @@ public class WebtoonReader extends BaseReader {
 
     @Override
     public void onPause() {
+        unsubscribeStatus();
+        super.onPause();
+    }
+
+    private void unsubscribeStatus() {
         if (subscription != null && !subscription.isUnsubscribed())
             subscription.unsubscribe();
-        super.onPause();
     }
 
     @Override
@@ -85,14 +89,18 @@ public class WebtoonReader extends BaseReader {
 
     @Override
     public void onPageListReady(List<Page> pages, int currentPage) {
-        this.pages = pages;
-        if (isResumed()) {
-            setPages();
+        if (this.pages != pages) {
+            this.pages = pages;
+            if (isResumed()) {
+                setPages();
+            }
         }
     }
 
     private void setPages() {
         if (pages != null) {
+            unsubscribeStatus();
+            adapter.clear();
             observeStatus(0);
         }
     }
@@ -112,8 +120,8 @@ public class WebtoonReader extends BaseReader {
         PublishSubject<Integer> statusSubject = PublishSubject.create();
         page.setStatusSubject(statusSubject);
 
-        if (subscription != null && !subscription.isUnsubscribed())
-            subscription.unsubscribe();
+        // Unsubscribe from the previous page
+        unsubscribeStatus();
 
         subscription = statusSubject
                 .startWith(page.getStatus())

+ 2 - 1
app/src/main/res/anim/fade_in.xml

@@ -4,5 +4,6 @@
         android:fromAlpha="0.0"
         android:toAlpha="1.0"
         android:interpolator="@android:anim/accelerate_interpolator"
-        android:duration="300" />
+        android:duration="300"
+        android:fillAfter="true"/>
 </set>

BIN
app/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png


BIN
app/src/main/res/drawable-ldpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-ldpi/ic_skip_previous_white_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_skip_previous_white_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_24dp.png


+ 19 - 0
app/src/main/res/menu/reader.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/action_previous_chapter"
+        android:title="@string/action_previous_chapter"
+        android:icon="@drawable/ic_skip_previous_white_24dp"
+        android:visible="false"
+        app:showAsAction="always" />
+
+    <item
+        android:id="@+id/action_next_chapter"
+        android:title="@string/action_next_chapter"
+        android:icon="@drawable/ic_skip_next_white_24dp"
+        android:visible="false"
+        app:showAsAction="always" />
+
+</menu>

+ 3 - 0
app/src/main/res/values/strings.xml

@@ -34,6 +34,9 @@
     <string name="action_next_unread">Next unread</string>
     <string name="action_start">Start</string>
     <string name="action_stop">Stop</string>
+    <string name="action_previous_chapter">Previous chapter</string>
+    <string name="action_next_chapter">Next chapter</string>
+
 
     <!-- Buttons -->
     <string name="button_ok">OK</string>