Added a tablet layout to manga details

The 3 people who can use this you better appericate it
This commit is contained in:
Jay 2020-04-13 20:10:50 -04:00
parent d09d3e0bda
commit 14c2ac6067
7 changed files with 273 additions and 121 deletions

View File

@ -22,7 +22,6 @@ class MangaDetailsAdapter(
var items: List<ChapterItem> = emptyList() var items: List<ChapterItem> = emptyList()
private var isAnimating = false
val delegate: MangaDetailsInterface = controller val delegate: MangaDetailsInterface = controller
val presenter = controller.presenter val presenter = controller.presenter
@ -51,17 +50,15 @@ class MangaDetailsAdapter(
fun performFilter() { fun performFilter() {
val s = getFilter(String::class.java) val s = getFilter(String::class.java)
if (s.isNullOrBlank()) { if (s.isNullOrBlank()) {
updateDataSet(items, isAnimating) updateDataSet(items)
} else { } else {
updateDataSet(items.filter { it.name.contains(s, true) || updateDataSet(items.filter { it.name.contains(s, true) ||
it.scanlator?.contains(s, true) == true }, isAnimating) it.scanlator?.contains(s, true) == true })
} }
isAnimating = false
} }
override fun onItemSwiped(position: Int, direction: Int) { override fun onItemSwiped(position: Int, direction: Int) {
super.onItemSwiped(position, direction) super.onItemSwiped(position, direction)
isAnimating = true
when (direction) { when (direction) {
ItemTouchHelper.RIGHT -> controller.bookmarkChapter(position) ItemTouchHelper.RIGHT -> controller.bookmarkChapter(position)
ItemTouchHelper.LEFT -> controller.toggleReadChapter(position) ItemTouchHelper.LEFT -> controller.toggleReadChapter(position)

View File

@ -19,6 +19,7 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@ -28,10 +29,12 @@ import android.view.ViewGroup
import android.view.ViewPropertyAnimator import android.view.ViewPropertyAnimator
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
@ -99,6 +102,7 @@ import eu.kanade.tachiyomi.util.system.ThemeUtil
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.pxToDp
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.getText import eu.kanade.tachiyomi.util.view.getText
@ -173,6 +177,15 @@ class MangaDetailsController : BaseController,
var refreshTracker: Int? = null var refreshTracker: Int? = null
private var textAnim: ViewPropertyAnimator? = null private var textAnim: ViewPropertyAnimator? = null
private var scrollAnim: ViewPropertyAnimator? = null private var scrollAnim: ViewPropertyAnimator? = null
var isTablet = false
// Tablet Layout
var tabletRecycler: RecyclerView? = null
/**
* Adapter containing a list of chapters.
*/
private var tabletAdapter: MangaDetailsAdapter? = null
/** /**
* Library search query. * Library search query.
@ -200,7 +213,7 @@ class MangaDetailsController : BaseController,
} }
override fun getTitle(): String? { override fun getTitle(): String? {
return if (toolbarIsColored) manga?.title else null return if (toolbarIsColored && !isTablet) manga?.title else null
} }
override fun onViewCreated(view: View) { override fun onViewCreated(view: View) {
@ -208,8 +221,28 @@ class MangaDetailsController : BaseController,
coverColor = null coverColor = null
// Init RecyclerView and adapter // Init RecyclerView and adapter
adapter = adapter = MangaDetailsAdapter(this, view.context)
MangaDetailsAdapter(this, view.context) isTablet = isTabletSize()
if (isTablet) {
tabletRecycler = RecyclerView(view.context)
linear_recycler_layout.addView(tabletRecycler, 0)
tabletRecycler?.updateLayoutParams<LinearLayout.LayoutParams> {
weight = 0.4f
height = ViewGroup.LayoutParams.MATCH_PARENT
width = ViewGroup.LayoutParams.MATCH_PARENT
}
tabletRecycler?.clipToPadding = false
tabletAdapter = MangaDetailsAdapter(this, view.context)
tabletRecycler?.adapter = tabletAdapter
tabletRecycler?.layoutManager = LinearLayoutManager(view.context)
val divider = View(view.context)
divider.setBackgroundColor(ContextCompat.getColor(view.context, R.color.divider))
linear_recycler_layout.addView(divider, 1)
divider.updateLayoutParams<LinearLayout.LayoutParams> {
height = ViewGroup.LayoutParams.MATCH_PARENT
width = 1.dpToPx
}
}
recycler.adapter = adapter recycler.adapter = adapter
adapter?.isSwipeEnabled = true adapter?.isSwipeEnabled = true
@ -232,11 +265,13 @@ class MangaDetailsController : BaseController,
activity!!.appbar.elevation = 0f activity!!.appbar.elevation = 0f
recycler.doOnApplyWindowInsets { v, insets, _ -> recycler.doOnApplyWindowInsets { v, insets, _ ->
v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)
tabletRecycler?.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)
headerHeight = appbarHeight + insets.systemWindowInsetTop headerHeight = appbarHeight + insets.systemWindowInsetTop
statusBarHeight = insets.systemWindowInsetTop statusBarHeight = insets.systemWindowInsetTop
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset) swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset)
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder) if (isTablet) v.updatePaddingRelative(top = headerHeight + 1.dpToPx)
?.setTopHeight(headerHeight) getHeader()?.setTopHeight(headerHeight)
fast_scroll_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> { fast_scroll_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = headerHeight topMargin = headerHeight
bottomMargin = insets.systemWindowInsetBottom bottomMargin = insets.systemWindowInsetBottom
@ -245,48 +280,57 @@ class MangaDetailsController : BaseController,
} }
presenter.onCreate() presenter.onCreate()
fast_scroller.translationX = if (showScroll) 0f else 25f.dpToPx fast_scroller.translationX = if (showScroll || isTablet) 0f else 25f.dpToPx
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
val atTop = !recycler.canScrollVertically(-1) val atTop = !recycler.canScrollVertically(-1)
val tY = getHeader()?.backdrop?.translationY ?: 0f if (!isTablet) {
getHeader()?.backdrop?.translationY = max(0f, tY + dy * 0.25f) val tY = getHeader()?.backdrop?.translationY ?: 0f
if (router?.backstack?.lastOrNull() getHeader()?.backdrop?.translationY = max(0f, tY + dy * 0.25f)
?.controller() == this@MangaDetailsController && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0 if (router?.backstack?.lastOrNull()
) { ?.controller() == this@MangaDetailsController && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
activity!!.appbar.y -= dy ) {
activity!!.appbar.y = MathUtils.clamp( activity!!.appbar.y -= dy
activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f activity!!.appbar.y = MathUtils.clamp(
) activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f
} )
val appBarY = activity?.appbar?.y ?: 0f }
if ((!atTop && !toolbarIsColored && (appBarY < (-headerHeight + 1) || (dy < 0 && appBarY == 0f))) || (atTop && toolbarIsColored)) { val appBarY = activity?.appbar?.y ?: 0f
colorToolbar(!atTop) if ((!atTop && !toolbarIsColored && (appBarY < (-headerHeight + 1) || (dy < 0 && appBarY == 0f))) || (atTop && toolbarIsColored)) {
colorToolbar(!atTop)
}
} else {
if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) {
colorToolbar(!atTop)
}
} }
if (atTop) { if (atTop) {
getHeader()?.backdrop?.translationY = 0f getHeader()?.backdrop?.translationY = 0f
activity!!.appbar.y = 0f activity!!.appbar.y = 0f
} }
val fPosition = if (!isTablet) {
(recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() val fPosition =
if (fPosition > 0 && !showScroll) { (recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
showScroll = true if (fPosition > 0 && !showScroll) {
scrollAnim?.cancel() showScroll = true
scrollAnim = fast_scroller.animate().setDuration(100).translationX(0f) scrollAnim?.cancel()
scrollAnim = fast_scroller.animate().setDuration(100).translationX(0f)
scrollAnim?.start() scrollAnim?.start()
} else if (fPosition <= 0 && showScroll) { } else if (fPosition <= 0 && showScroll) {
showScroll = false showScroll = false
scrollAnim?.cancel() scrollAnim?.cancel()
scrollAnim = fast_scroller.animate().setDuration(100).translationX(25f.dpToPx) scrollAnim =
scrollAnim?.start() fast_scroller.animate().setDuration(100).translationX(25f.dpToPx)
scrollAnim?.start()
}
} }
} }
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
val atTop = !recycler.canScrollVertically(-1) val atTop = !recycler.canScrollVertically(-1)
if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (newState == RecyclerView.SCROLL_STATE_IDLE && !isTablet) {
if (router?.backstack?.lastOrNull() if (router?.backstack?.lastOrNull()
?.controller() == this@MangaDetailsController && statusBarHeight > -1 && activity != null && ?.controller() == this@MangaDetailsController && statusBarHeight > -1 && activity != null &&
activity!!.appbar.height > 0 activity!!.appbar.height > 0
@ -415,8 +459,7 @@ class MangaDetailsController : BaseController,
) )
else it?.getDarkVibrantColor(colorBack)) ?: colorBack else it?.getDarkVibrantColor(colorBack)) ?: colorBack
coverColor = backDropColor coverColor = backDropColor
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder) getHeader()?.setBackDrop(backDropColor)
?.setBackDrop(backDropColor)
if (toolbarIsColored) { if (toolbarIsColored) {
val translucentColor = ColorUtils.setAlphaComponent(backDropColor, 175) val translucentColor = ColorUtils.setAlphaComponent(backDropColor, 175)
(activity as MainActivity).toolbar.setBackgroundColor(translucentColor) (activity as MainActivity).toolbar.setBackgroundColor(translucentColor)
@ -456,11 +499,33 @@ class MangaDetailsController : BaseController,
download.progress) download.progress)
} }
private fun isTabletSize(): Boolean {
val activity = activity ?: return false
if ((activity.resources.configuration.screenLayout and Configuration
.SCREENLAYOUT_SIZE_MASK) < Configuration.SCREENLAYOUT_SIZE_LARGE)
return false
val displayMetrics = DisplayMetrics()
activity.windowManager?.defaultDisplay?.getMetrics(displayMetrics)
return displayMetrics.widthPixels.pxToDp >= 720
}
fun hasTabletHeight(): Boolean {
val activity = activity ?: return false
if ((activity.resources.configuration.screenLayout and Configuration
.SCREENLAYOUT_SIZE_MASK) < Configuration.SCREENLAYOUT_SIZE_LARGE) return false
val displayMetrics = DisplayMetrics()
activity.windowManager?.defaultDisplay?.getMetrics(displayMetrics)
return displayMetrics.heightPixels.pxToDp >= 720
}
private fun getHolder(chapter: Chapter): ChapterHolder? { private fun getHolder(chapter: Chapter): ChapterHolder? {
return recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder return recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder
} }
private fun getHeader(): MangaHeaderHolder? = recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder private fun getHeader(): MangaHeaderHolder? {
return if (isTablet) tabletRecycler?.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder
else recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder
}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type) super.onChangeStarted(handler, type)
@ -719,9 +784,10 @@ class MangaDetailsController : BaseController,
setOnQueryTextChangeListener(searchView) { setOnQueryTextChangeListener(searchView) {
query = it ?: "" query = it ?: ""
if (query.isNotEmpty()) { if (!isTablet) {
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)?.collapse() if (query.isNotEmpty()) getHeader()?.collapse()
} else (recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)?.expand() else getHeader()?.expand()
}
adapter?.setFilter(query) adapter?.setFilter(query)
adapter?.performFilter() adapter?.performFilter()
@ -1084,8 +1150,7 @@ class MangaDetailsController : BaseController,
if (!manga.favorite) { if (!manga.favorite) {
toggleMangaFavorite() toggleMangaFavorite()
} else { } else {
val headerHolder = val headerHolder = getHeader() ?: return
recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder ?: return
val popup = PopupMenu(view!!.context, headerHolder.favorite_button) val popup = PopupMenu(view!!.context, headerHolder.favorite_button)
popup.menu.add(R.string.remove_from_library) popup.menu.add(R.string.remove_from_library)
@ -1152,8 +1217,7 @@ class MangaDetailsController : BaseController,
} }
}) })
} }
val favButton = (recycler.findViewHolderForAdapterPosition(0) val favButton = getHeader()?.favorite_button
as? MangaHeaderHolder)?.favorite_button
(activity as? MainActivity)?.setUndoSnackBar(snack, favButton) (activity as? MainActivity)?.setUndoSnackBar(snack, favButton)
} }
@ -1207,8 +1271,7 @@ class MangaDetailsController : BaseController,
} }
fun refreshTracker() { fun refreshTracker() {
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder) getHeader()?.updateTracking()
?.updateTracking()
} }
fun trackRefreshDone() { fun trackRefreshDone() {
@ -1276,7 +1339,12 @@ class MangaDetailsController : BaseController,
* Called to set the last used catalogue at the top of the view. * Called to set the last used catalogue at the top of the view.
*/ */
private fun addMangaHeader() { private fun addMangaHeader() {
if (adapter?.scrollableHeaders?.isEmpty() == true) { if (tabletAdapter?.scrollableHeaders?.isEmpty() == true) {
tabletAdapter?.removeAllScrollableHeaders()
tabletAdapter?.addScrollableHeader(presenter.headerItem)
adapter?.removeAllScrollableHeaders()
adapter?.addScrollableHeader(presenter.tabletChapterHeaderItem!!)
} else if (!isTablet && adapter?.scrollableHeaders?.isEmpty() == true) {
adapter?.removeAllScrollableHeaders() adapter?.removeAllScrollableHeaders()
adapter?.addScrollableHeader(presenter.headerItem) adapter?.addScrollableHeader(presenter.headerItem)
} }

View File

@ -75,8 +75,15 @@ class MangaDetailsPresenter(
private set private set
var headerItem = MangaHeaderItem(manga, controller.fromCatalogue) var headerItem = MangaHeaderItem(manga, controller.fromCatalogue)
var tabletChapterHeaderItem: MangaHeaderItem? = null
fun onCreate() { fun onCreate() {
headerItem.startExpanded = controller.hasTabletHeight() || headerItem.startExpanded
headerItem.isTablet = controller.isTablet
if (controller.isTablet) {
tabletChapterHeaderItem = MangaHeaderItem(manga, false)
tabletChapterHeaderItem?.isChapterHeader = true
}
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked() isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
headerItem.isLocked = isLockedFromSearch headerItem.isLocked = isLockedFromSearch
downloadManager.addListener(this) downloadManager.addListener(this)
@ -223,6 +230,8 @@ class MangaDetailsPresenter(
* @return an observable of the list of chapters filtered and sorted. * @return an observable of the list of chapters filtered and sorted.
*/ */
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> { private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
if (isLockedFromSearch)
return chapterList
var chapters = chapterList var chapters = chapterList
if (onlyUnread()) { if (onlyUnread()) {
chapters = chapters.filter { !it.read } chapters = chapters.filter { !it.read }

View File

@ -32,60 +32,57 @@ import kotlinx.android.synthetic.main.manga_header_item.*
class MangaHeaderHolder( class MangaHeaderHolder(
private val view: View, private val view: View,
private val adapter: MangaDetailsAdapter, private val adapter: MangaDetailsAdapter,
startExpanded: Boolean startExpanded: Boolean,
isTablet: Boolean = false
) : BaseFlexibleViewHolder(view, adapter) { ) : BaseFlexibleViewHolder(view, adapter) {
init { init {
start_reading_button.setOnClickListener { adapter.delegate.readNextChapter() }
top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
height = adapter.delegate.topCoverHeight()
}
more_button.setOnClickListener { expandDesc() }
manga_summary.setOnClickListener { expandDesc() }
manga_summary.setOnLongClickListener {
if (manga_summary.isTextSelectable && !adapter.recyclerView.canScrollVertically(-1)) {
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled = false
}
false
}
manga_summary.setOnTouchListener { _, event ->
if (event.actionMasked == MotionEvent.ACTION_UP)
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled = true
false
}
less_button.setOnClickListener {
manga_summary.setTextIsSelectable(false)
manga_summary.maxLines = 3
manga_summary.setOnClickListener { expandDesc() }
manga_genres_tags.gone()
less_button.gone()
more_button_group.visible()
}
manga_genres_tags.setOnTagClickListener {
adapter.delegate.tagClicked(it)
}
chapter_layout.setOnClickListener { adapter.delegate.showChapterFilter() } chapter_layout.setOnClickListener { adapter.delegate.showChapterFilter() }
webview_button.setOnClickListener { adapter.delegate.openInWebView() } if (start_reading_button != null) {
share_button.setOnClickListener { adapter.delegate.prepareToShareManga() } start_reading_button.setOnClickListener { adapter.delegate.readNextChapter() }
favorite_button.setOnClickListener { top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
adapter.delegate.favoriteManga(false) height = adapter.delegate.topCoverHeight()
}
more_button.setOnClickListener { expandDesc() }
manga_summary.setOnClickListener { expandDesc() }
manga_summary.setOnLongClickListener {
if (manga_summary.isTextSelectable && !adapter.recyclerView.canScrollVertically(-1)) {
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled = false
}
false
}
manga_summary.setOnTouchListener { _, event ->
if (event.actionMasked == MotionEvent.ACTION_UP) (adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled =
true
false
}
less_button.setOnClickListener { collapseDesc() }
manga_genres_tags.setOnTagClickListener {
adapter.delegate.tagClicked(it)
}
webview_button.setOnClickListener { adapter.delegate.openInWebView() }
share_button.setOnClickListener { adapter.delegate.prepareToShareManga() }
favorite_button.setOnClickListener {
adapter.delegate.favoriteManga(false)
}
favorite_button.setOnLongClickListener {
adapter.delegate.favoriteManga(true)
true
}
manga_full_title.setOnLongClickListener {
adapter.delegate.copyToClipboard(manga_full_title.text.toString(), R.string.title)
true
}
manga_author.setOnLongClickListener {
adapter.delegate.copyToClipboard(manga_author.text.toString(), R.string.author)
true
}
manga_cover.setOnClickListener { adapter.delegate.zoomImageFromThumb(cover_card) }
track_button.setOnClickListener { adapter.delegate.showTrackingSheet() }
if (startExpanded) expandDesc()
else collapseDesc()
if (isTablet) chapter_layout.gone()
} }
favorite_button.setOnLongClickListener {
adapter.delegate.favoriteManga(true)
true
}
manga_full_title.setOnLongClickListener {
adapter.delegate.copyToClipboard(manga_full_title.text.toString(), R.string.title)
true
}
manga_author.setOnLongClickListener {
adapter.delegate.copyToClipboard(manga_author.text.toString(), R.string.author)
true
}
manga_cover.setOnClickListener { adapter.delegate.zoomImageFromThumb(cover_card) }
track_button.setOnClickListener { adapter.delegate.showTrackingSheet() }
if (startExpanded)
expandDesc()
} }
private fun expandDesc() { private fun expandDesc() {
@ -98,6 +95,22 @@ class MangaHeaderHolder(
} }
} }
private fun collapseDesc() {
manga_summary.setTextIsSelectable(false)
manga_summary.maxLines = 3
manga_summary.setOnClickListener { expandDesc() }
manga_genres_tags.gone()
less_button.gone()
more_button_group.visible()
}
fun bindChapters() {
val presenter = adapter.delegate.mangaPresenter()
val count = presenter.chapters.size
chapters_title.text = itemView.resources.getQuantityString(R.plurals.chapters, count, count)
filters_text.text = presenter.currentFilters()
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun bind(item: MangaHeaderItem, manga: Manga) { fun bind(item: MangaHeaderItem, manga: Manga) {
val presenter = adapter.delegate.mangaPresenter() val presenter = adapter.delegate.mangaPresenter()

View File

@ -8,13 +8,15 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean) : class MangaHeaderItem(val manga: Manga, var startExpanded: Boolean) :
AbstractFlexibleItem<MangaHeaderHolder>() { AbstractFlexibleItem<MangaHeaderHolder>() {
var isTablet = false
var isChapterHeader = false
var isLocked = false var isLocked = false
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return R.layout.manga_header_item return if (isChapterHeader) R.layout.chapter_header_item else R.layout.manga_header_item
} }
override fun isSelectable(): Boolean { override fun isSelectable(): Boolean {
@ -26,7 +28,7 @@ class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean) :
} }
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder {
return MangaHeaderHolder(view, adapter as MangaDetailsAdapter, startExpanded) return MangaHeaderHolder(view, adapter as MangaDetailsAdapter, startExpanded, isTablet)
} }
override fun bindViewHolder( override fun bindViewHolder(
@ -35,7 +37,8 @@ class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean) :
position: Int, position: Int,
payloads: MutableList<Any?>? payloads: MutableList<Any?>?
) { ) {
holder.bind(this, manga) if (isChapterHeader) holder.bindChapters()
else holder.bind(this, manga)
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/chapter_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectable_list_drawable"
android:tooltipText="@string/sort_and_filter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/start_reading_button">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/chapters_title"
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:maxLines="1"
android:text="@string/chapters"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/filters_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/filter_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:background="@null"
android:padding="5dp"
android:src="@drawable/ic_filter_list_white_24dp"
android:tint="?colorAccent"
app:layout_constraintBottom_toBottomOf="@id/chapters_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/chapters_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/filters_text"
tools:text="Read, Unread, Bookmarked, Downloaded, All"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="6dp"
android:maxLines="2"
android:padding="5dp"
android:textAlignment="textEnd"
android:textColor="?android:textColorHint"
app:layout_constraintBaseline_toBaselineOf="@id/chapters_title"
app:layout_constraintBottom_toBottomOf="@id/filter_button"
app:layout_constraintEnd_toStartOf="@id/filter_button"
app:layout_constraintStart_toEndOf="@+id/chapters_title"
app:layout_constraintTop_toTopOf="@id/filter_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -13,17 +13,21 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:colorBackground"> android:background="?android:colorBackground">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler" <LinearLayout
android:id="@+id/linear_recycler_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:orientation="horizontal">
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent" <androidx.recyclerview.widget.RecyclerView
app:layout_constraintEnd_toEndOf="parent" android:id="@+id/recycler"
app:layout_constraintStart_toStartOf="parent" android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="@id/chapters_title" android:layout_height="match_parent"
tools:listitem="@layout/chapters_item"/> android:clipToPadding="false"
android:layout_weight="0.25"
tools:listitem="@layout/chapters_item" />
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -33,16 +37,16 @@
<com.reddit.indicatorfastscroll.FastScrollerView <com.reddit.indicatorfastscroll.FastScrollerView
android:id="@+id/fast_scroller" android:id="@+id/fast_scroller"
android:textColor="?android:attr/textColorPrimary"
app:iconColor="?android:attr/textColorPrimary"
android:layout_width="25dp" android:layout_width="25dp"
android:layout_height="0dp" android:layout_height="0dp"
android:elevation="10dp"
android:layout_gravity="end" android:layout_gravity="end"
android:paddingTop="8dp" android:elevation="10dp"
android:paddingBottom="8dp"
android:paddingStart="1dp" android:paddingStart="1dp"
android:paddingTop="8dp"
android:paddingEnd="0dp" android:paddingEnd="0dp"
android:paddingBottom="8dp"
android:textColor="?android:attr/textColorPrimary"
app:iconColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -52,15 +56,15 @@
android:id="@+id/text_view_m" android:id="@+id/text_view_m"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:alpha="0"
tools:alpha="1"
android:layout_marginEnd="50dp" android:layout_marginEnd="50dp"
android:alpha="0"
android:background="@drawable/round_textview_background" android:background="@drawable/round_textview_background"
android:backgroundTint="@color/md_grey_800_85" android:backgroundTint="@color/md_grey_800_85"
android:padding="8dp" android:padding="8dp"
android:textColor="@android:color/white" android:textColor="@android:color/white"
app:layout_constraintEnd_toStartOf="@id/fast_scroller" app:layout_constraintEnd_toStartOf="@id/fast_scroller"
app:layout_constraintTop_toTopOf="@id/fast_scroller" app:layout_constraintTop_toTopOf="@id/fast_scroller"
tools:alpha="1"
tools:text="sdfsdf" /> tools:text="sdfsdf" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@ -76,7 +80,6 @@
tools:background="@color/md_black_1000" /> tools:background="@color/md_black_1000" />
<ImageView <ImageView
android:id="@+id/manga_cover_full" android:id="@+id/manga_cover_full"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -84,9 +87,9 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:elevation="10dp"
android:translationZ="20dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:contentDescription="@string/cover_of_image" android:contentDescription="@string/cover_of_image"
android:elevation="10dp"
android:translationZ="20dp"
android:visibility="invisible" /> android:visibility="invisible" />
</FrameLayout> </FrameLayout>