Browse Source

Merge pull request #225 from NoodleMage/manga_chapters

Updated manga chapters UI
inorichi 9 years ago
parent
commit
70cf085df9

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt

@@ -76,12 +76,12 @@ class LibraryFragment : BaseRxFragment<LibraryPresenter>(), ActionMode.Callback
 
 
     /**
-     * TODO
+     * Status of isFilterDownloaded
      */
     var isFilterDownloaded = false
 
     /**
-     * TODO
+     * Status of isFilterUnread
      */
     var isFilterUnread = false
 

+ 50 - 32
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt

@@ -1,7 +1,9 @@
 package eu.kanade.tachiyomi.ui.manga.chapter
 
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.content.Intent
 import android.os.Bundle
-import android.support.v4.content.ContextCompat
 import android.support.v7.view.ActionMode
 import android.support.v7.widget.LinearLayoutManager
 import android.view.*
@@ -17,6 +19,7 @@ import eu.kanade.tachiyomi.ui.base.decoration.DividerItemDecoration
 import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
 import eu.kanade.tachiyomi.ui.manga.MangaActivity
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
+import eu.kanade.tachiyomi.util.getCoordinates
 import eu.kanade.tachiyomi.util.getResourceDrawable
 import eu.kanade.tachiyomi.util.toast
 import kotlinx.android.synthetic.main.fragment_manga_chapters.*
@@ -71,10 +74,22 @@ class ChaptersFragment : BaseRxFragment<ChaptersPresenter>(), ActionMode.Callbac
 
         swipe_refresh.setOnRefreshListener { fetchChapters() }
 
-        next_unread_btn.setOnClickListener { v ->
+        fab.setOnClickListener { v ->
             val chapter = presenter.getNextUnreadChapter()
             if (chapter != null) {
-                openChapter(chapter)
+                // Create animation listener
+                var revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator) {
+                        // On done open chapter
+                        openChapter(chapter, true)
+                    }
+                }
+
+                // Get coordinates and start animation
+                val coordinates = fab.getCoordinates()
+                if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
+                    openChapter(chapter)
+                }
             } else {
                 context.toast(R.string.no_next_chapter)
             }
@@ -91,37 +106,49 @@ class ChaptersFragment : BaseRxFragment<ChaptersPresenter>(), ActionMode.Callbac
         super.onPause()
     }
 
+    override fun onResume() {
+        // Check if animation view is visible
+        if (reveal_view.visibility == View.VISIBLE) {
+            // Show the unReveal effect
+            var coordinates = fab.getCoordinates()
+            reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920)
+        }
+        super.onResume()
+    }
+
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
         inflater.inflate(R.menu.chapters, menu)
+        menu.findItem(R.id.action_filter_unread).isChecked = presenter.onlyUnread()
+        menu.findItem(R.id.action_filter_downloaded).isChecked = presenter.onlyDownloaded()
     }
 
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.action_display_mode -> showDisplayModeDialog()
             R.id.manga_download -> showDownloadDialog()
+            R.id.action_filter_unread -> {
+                item.isChecked = !item.isChecked
+                presenter.setReadFilter(item.isChecked)
+            }
+            R.id.action_filter_downloaded -> {
+                item.isChecked = !item.isChecked
+                presenter.setDownloadedFilter(item.isChecked)
+            }
+            R.id.action_filter_empty -> {
+                presenter.setReadFilter(false)
+                presenter.setDownloadedFilter(false)
+                activity.supportInvalidateOptionsMenu();
+            }
+            R.id.action_sort -> presenter.revertSortOrder()
             else -> return super.onOptionsItemSelected(item)
         }
         return true
     }
 
     fun onNextManga(manga: Manga) {
-        // Remove listeners before setting the values
-        show_unread.setOnCheckedChangeListener(null)
-        show_downloaded.setOnCheckedChangeListener(null)
-        sort_btn.setOnClickListener(null)
-
         // Set initial values
         setReadFilter()
         setDownloadedFilter()
-        setSortIcon()
-
-        // Init listeners
-        show_unread.setOnCheckedChangeListener { arg, isChecked -> presenter.setReadFilter(isChecked) }
-        show_downloaded.setOnCheckedChangeListener { v, isChecked -> presenter.setDownloadedFilter(isChecked) }
-        sort_btn.setOnClickListener {
-            presenter.revertSortOrder()
-            setSortIcon()
-        }
     }
 
     fun onNextChapters(chapters: List<Chapter>) {
@@ -158,9 +185,12 @@ class ChaptersFragment : BaseRxFragment<ChaptersPresenter>(), ActionMode.Callbac
     val isCatalogueManga: Boolean
         get() = (activity as MangaActivity).isCatalogueManga
 
-    protected fun openChapter(chapter: Chapter) {
+    protected fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) {
         presenter.onOpenChapter(chapter)
         val intent = ReaderActivity.newIntent(activity)
+        if (hasAnimation) {
+            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
+        }
         startActivity(intent)
     }
 
@@ -341,23 +371,11 @@ class ChaptersFragment : BaseRxFragment<ChaptersPresenter>(), ActionMode.Callbac
         actionMode?.title = getString(R.string.label_selected, count)
     }
 
-    fun setSortIcon() {
-        sort_btn?.let {
-            val aToZ = presenter.sortOrder()
-            it.setImageResource(if (!aToZ) R.drawable.ic_expand_less_white_36dp else R.drawable.ic_expand_more_white_36dp)
-        }
-    }
-
     fun setReadFilter() {
-        show_unread?.let {
-            it.isChecked = presenter.onlyUnread()
-        }
+        this.activity.supportInvalidateOptionsMenu()
     }
 
     fun setDownloadedFilter() {
-        show_downloaded?.let {
-            it.isChecked = presenter.onlyDownloaded()
-        }
+        this.activity.supportInvalidateOptionsMenu()
     }
-
 }

+ 19 - 0
app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt

@@ -0,0 +1,19 @@
+package eu.kanade.tachiyomi.util
+
+import android.graphics.Point
+import android.view.View
+
+/**
+ * Returns coordinates of view.
+ * Used for animation
+ *
+ * @return coordinates of view
+ */
+fun View.getCoordinates(): Point
+{
+    var cx = (this.left + this.right) / 2;
+    var cy = (this.top + this.bottom) / 2;
+
+    return Point(cx, cy)
+}
+

+ 79 - 0
app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt

@@ -0,0 +1,79 @@
+package eu.kanade.tachiyomi.widget
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.annotation.TargetApi
+import android.content.Context
+import android.os.Build
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewAnimationUtils
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+        View(context, attrs) {
+
+    /**
+     * Hides the animation view with a animation
+     *
+     * @param centerX x starting point
+     * @param centerY y starting point
+     * @param initialRadius size of radius of animation
+     */
+    fun hideRevealEffect(centerX: Int, centerY: Int, initialRadius: Int) {
+        if (Build.VERSION.SDK_INT >= 21) {
+
+            // Make the view visible.
+            this.visibility = View.VISIBLE
+
+            // Create the animation (the final radius is zero).
+            val anim = ViewAnimationUtils.createCircularReveal(
+                    this, centerX, centerY, initialRadius.toFloat(), 0f)
+
+            // Set duration of animation.
+            anim.duration = 500
+
+            // make the view invisible when the animation is done
+            anim.addListener(object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    super.onAnimationEnd(animation)
+                    [email protected] = View.INVISIBLE
+                }
+            })
+
+            anim.start()
+        }
+    }
+
+    /**
+     * Fills the animation view with a animation
+     *
+     * @param centerX x starting point
+     * @param centerY y starting point
+     * @param listener animation listener
+     *
+     * @return sdk version lower then 21
+     */
+    fun showRevealEffect(centerX: Int, centerY: Int, listener: Animator.AnimatorListener): Boolean {
+        if (Build.VERSION.SDK_INT >= 21) {
+
+            this.visibility = View.VISIBLE
+
+            val height = this.height
+
+            // Create animation
+            val anim = ViewAnimationUtils.createCircularReveal(
+                    this, centerX, centerY, 0f, height.toFloat())
+
+            // Set duration of animation
+            anim.duration = 350
+
+            anim.addListener(listener)
+            anim.start()
+            return true
+        }
+        return false
+    }
+
+
+}

+ 9 - 0
app/src/main/res/drawable/ic_sort_by_alpha_white_24dp.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportHeight="24.0"
+        android:viewportWidth="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M14.94,4.66h-4.72l2.36,-2.36zM10.25,19.37h4.66l-2.33,2.33zM6.1,6.27L1.6,17.73h1.84l0.92,-2.45h5.11l0.92,2.45h1.84L7.74,6.27L6.1,6.27zM4.97,13.64l1.94,-5.18 1.94,5.18L4.97,13.64zM15.73,16.14h6.12v1.59h-8.53v-1.29l5.92,-8.56h-5.88v-1.6h8.3v1.26l-5.93,8.6z"/>
+</vector>

+ 17 - 75
app/src/main/res/layout/fragment_manga_chapters.xml

@@ -1,11 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.design.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
                 xmlns:app="http://schemas.android.com/apk/res-auto"
                 xmlns:tools="http://schemas.android.com/tools"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:orientation="vertical">
 
+    <eu.kanade.tachiyomi.widget.RevealAnimationView
+        android:id="@+id/reveal_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="?attr/colorAccent"
+        android:elevation="5dp"
+        android:visibility="invisible"
+        />
+
     <android.support.v4.widget.SwipeRefreshLayout
         android:id="@+id/swipe_refresh"
         android:layout_width="match_parent"
@@ -26,78 +36,10 @@
 
     </android.support.v4.widget.SwipeRefreshLayout>
 
+    <android.support.design.widget.FloatingActionButton
+        android:id="@+id/fab"
+        style="@style/Theme.Widget.FAB"
+        app:layout_anchor="@id/recycler"
+        app:srcCompat="@drawable/ic_play_arrow_white_24dp"/>
 
-    <RelativeLayout
-        android:id="@+id/toolbar_bottom"
-        android:layout_width="match_parent"
-        android:layout_height="?attr/actionBarSize"
-        android:layout_alignParentBottom="true"
-        android:background="?attr/colorPrimary"
-        android:elevation="4dp"
-        android:gravity="top|start"
-        android:paddingLeft="12dp"
-        android:paddingRight="12dp">
-
-        <ImageView
-            android:id="@+id/sort_btn"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="center"
-            android:background="?android:selectableItemBackground"
-            android:title="@string/action_sort_up"
-            tools:src="@drawable/ic_expand_less_white_36dp"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_toEndOf="@+id/sort_btn"
-            android:layout_toLeftOf="@+id/next_unread_btn"
-            android:layout_toRightOf="@+id/sort_btn"
-            android:gravity="center_vertical">
-
-            <View
-                android:layout_width="1dp"
-                android:layout_height="match_parent"
-                android:layout_margin="10dp"
-                android:background="@color/md_white_1000"/>
-
-            <android.support.v7.widget.AppCompatCheckBox
-                android:id="@+id/show_unread"
-                style="@style/Theme.Widget.CheckBox.Light"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:checkable="true"
-                android:text="@string/action_show_unread"
-                android:title="@string/action_show_unread"/>
-
-            <android.support.v7.widget.AppCompatCheckBox
-                android:id="@+id/show_downloaded"
-                style="@style/Theme.Widget.CheckBox.Light"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:checkable="true"
-                android:text="@string/action_show_downloaded"
-                android:title="@string/action_show_downloaded"/>
-
-            <View
-                android:layout_width="1dp"
-                android:layout_height="match_parent"
-                android:layout_margin="10dp"
-                android:background="@color/md_white_1000"/>
-
-        </LinearLayout>
-
-        <android.support.v7.widget.AppCompatImageView
-            android:id="@+id/next_unread_btn"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentEnd="true"
-            android:layout_alignParentRight="true"
-            android:title="@string/action_next_unread"
-            app:srcCompat="@drawable/ic_play_arrow_white_36dp"/>
-
-    </RelativeLayout>
-
-</RelativeLayout>
+</android.support.design.widget.CoordinatorLayout>

+ 9 - 9
app/src/main/res/layout/item_chapter.xml

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:app="http://schemas.android.com/apk/res-auto"
                 xmlns:tools="http://schemas.android.com/tools"
                 android:layout_width="fill_parent"
                 android:layout_height="?android:attr/listPreferredItemHeight"
-                xmlns:app="http://schemas.android.com/apk/res-auto"
                 android:background="?attr/selectable_list_drawable">
 
 
@@ -25,37 +25,38 @@
 
             <TextView
                 android:id="@+id/chapter_pages"
+                style="@style/TextAppearance.Regular.Caption.Hint"
                 android:layout_width="wrap_content"
                 android:layout_height="fill_parent"
                 android:layout_alignParentTop="true"
                 android:layout_centerHorizontal="true"
                 android:ellipsize="marquee"
                 android:singleLine="true"
-                style="@style/TextAppearance.Regular.Caption.Hint"
                 tools:text="Pages: 45"/>
 
             <TextView
                 android:id="@+id/chapter_date"
+                style="@style/TextAppearance.Regular.Caption"
                 android:layout_width="wrap_content"
                 android:layout_height="fill_parent"
                 android:ellipsize="marquee"
                 android:singleLine="true"
-                style="@style/TextAppearance.Regular.Body1"
                 tools:text="22/02/2016"/>
 
             <TextView
                 android:id="@+id/download_text"
+                style="@style/TextAppearance.Regular.Caption.Hint"
                 android:layout_width="wrap_content"
                 android:layout_height="fill_parent"
                 android:layout_alignParentEnd="true"
                 android:layout_alignParentRight="true"
                 android:layout_centerVertical="true"
-                android:textAllCaps="true"
-                style="@style/TextAppearance.Regular.Caption.Hint"/>
+                android:textAllCaps="true"/>
         </RelativeLayout>
 
         <TextView
             android:id="@+id/chapter_title"
+            style="@style/TextAppearance.Regular.Body1"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_above="@+id/relativeLayout"
@@ -68,8 +69,7 @@
             android:layout_marginRight="30dp"
             android:ellipsize="middle"
             android:gravity="center_vertical"
-            android:maxLines="1"
-            style="@style/TextAppearance.Regular.SubHeading"
+            android:maxLines="2"
             tools:text="Title"/>
 
 
@@ -93,8 +93,8 @@
             android:layout_alignParentEnd="false"
             android:layout_alignParentRight="true"
             android:layout_alignParentTop="true"
-            app:srcCompat="@drawable/ic_more_horiz_black_24dp"
-            android:tint="?android:attr/textColorPrimary"/>
+            android:tint="?android:attr/textColorPrimary"
+            app:srcCompat="@drawable/ic_more_horiz_black_24dp"/>
 
     </RelativeLayout>
 

+ 28 - 2
app/src/main/res/menu/chapters.xml

@@ -3,12 +3,38 @@
       xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <item
-        android:title="@string/action_display_mode"
+        android:id="@+id/action_filter"
+        android:icon="@drawable/ic_filter_list_white_24dp"
+        android:title="@string/action_filter"
+        app:showAsAction="ifRoom">
+        <menu>
+            <item
+                android:id="@+id/action_filter_downloaded"
+                android:checkable="true"
+                android:title="@string/action_filter_downloaded"/>
+            <item
+                android:id="@+id/action_filter_unread"
+                android:checkable="true"
+                android:title="@string/action_filter_unread"/>
+            <item
+                android:id="@+id/action_filter_empty"
+                android:title="@string/action_filter_empty"/>
+        </menu>
+    </item>
+
+    <item
+        android:id="@+id/action_sort"
+        android:icon="@drawable/ic_sort_by_alpha_white_24dp"
+        android:title="@string/action_sort"
+        app:showAsAction="ifRoom"/>
+
+    <item
         android:id="@+id/action_display_mode"
+        android:title="@string/action_display_mode"
         app:showAsAction="never" />
 
     <item
-        android:title="@string/manga_download"
         android:id="@+id/manga_download"
+        android:title="@string/manga_download"
         app:showAsAction="never" />
 </menu>

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

@@ -48,6 +48,7 @@
     <string name="action_open_in_browser">Open in browser</string>
     <string name="action_display_mode">Change display mode</string>
     <string name="action_cancel">Cancel</string>
+    <string name="action_sort">Sort</string>
 
     <!-- Buttons -->
     <string name="button_ok">OK</string>