Always using autofit for single list + start at header on app start/tab return

Moving some classes outside of library controller
This commit is contained in:
Jay 2020-02-18 22:37:36 -08:00
parent da2f3d4524
commit 18cbb72f79
8 changed files with 114 additions and 155 deletions

View File

@ -31,20 +31,20 @@ import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.library.HeightTopWindowInsetsListener
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.webview.WebViewActivity import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.view.HeightTopWindowInsetsListener
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.inflate
import eu.kanade.tachiyomi.util.view.marginBottom
import eu.kanade.tachiyomi.util.view.marginTop import eu.kanade.tachiyomi.util.view.marginTop
import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.view.marginBottom
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.catalogue_controller.* import kotlinx.android.synthetic.main.catalogue_controller.*
import kotlinx.android.synthetic.main.main_activity.* import kotlinx.android.synthetic.main.main_activity.*

View File

@ -5,16 +5,13 @@ import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.ArrayAdapter
import android.widget.Spinner import android.widget.Spinner
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
@ -213,6 +210,8 @@ class LibraryController(
*/ */
private lateinit var recycler: RecyclerView private lateinit var recycler: RecyclerView
var libraryLayout = preferences.libraryLayout().getOrDefault()
private var usePager: Boolean = !preferences.libraryAsSingleList().getOrDefault() private var usePager: Boolean = !preferences.libraryAsSingleList().getOrDefault()
init { init {
@ -255,26 +254,20 @@ class LibraryController(
} }
else { else {
adapter = LibraryCategoryAdapter(this) adapter = LibraryCategoryAdapter(this)
recycler = if (preferences.libraryLayout().getOrDefault() == 0) { recycler = (recycler_layout.inflate(R.layout.library_grid_recycler) as
(recycler_layout.inflate(R.layout.library_list_recycler) as RecyclerView).apply { AutofitRecyclerView).apply {
layoutManager = LinearLayoutManager(context) spanCount = if (libraryLayout == 0) 1 else mangaPerRow
} manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
} else { override fun getSpanSize(position: Int): Int {
(recycler_layout.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply { if (libraryLayout == 0) return 1
spanCount = mangaPerRow val item = this@LibraryController.adapter.getItem(position)
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() { return if (item is LibraryHeaderItem) manager.spanCount else 1
override fun getSpanSize(position: Int): Int { }
val item = this@LibraryController.adapter.getItem(position) })
return if (item is LibraryHeaderItem)
manager.spanCount else 1
}
})
}
} }
recycler.setHasFixedSize(true) recycler.setHasFixedSize(true)
recycler.adapter = adapter recycler.adapter = adapter
//adapter.setStickyHeaders(true)
recycler_layout.addView(recycler) recycler_layout.addView(recycler)
adapter.fastScroller = fast_scroller adapter.fastScroller = fast_scroller
recycler.addOnScrollListener(scrollListener) recycler.addOnScrollListener(scrollListener)
@ -286,8 +279,6 @@ class LibraryController(
arrayOf(resources!!.getString(R.string.label_library))) arrayOf(resources!!.getString(R.string.label_library)))
spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text) spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text)
spinner.adapter = spinnerAdapter spinner.adapter = spinnerAdapter
//spinnerAdapter?.setCustomText(resources?.getString(R.string.label_library))
} }
@ -295,7 +286,6 @@ class LibraryController(
createActionModeIfNeeded() createActionModeIfNeeded()
} }
//bottom_sheet.onCreate(pager_layout) //bottom_sheet.onCreate(pager_layout)
bottom_sheet.onCreate(if (usePager) pager_layout else recycler_layout) bottom_sheet.onCreate(if (usePager) pager_layout else recycler_layout)
@ -440,7 +430,6 @@ class LibraryController(
} }
adapter.setItems(mangaMap) adapter.setItems(mangaMap)
val position = if (freshStart) adapter.indexOf(activeCategory) + 1 else null
spinner.onItemSelectedListener = null spinner.onItemSelectedListener = null
spinnerAdapter = SpinnerAdapter(view!!.context, R.layout.library_spinner_textview, spinnerAdapter = SpinnerAdapter(view!!.context, R.layout.library_spinner_textview,
@ -450,8 +439,6 @@ class LibraryController(
spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1)) spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1))
/* spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory
}?.name ?: resources?.getString(R.string.label_library))*/
if (!freshStart) { if (!freshStart) {
justStarted = false justStarted = false
if (recycler_layout.alpha == 0f) if (recycler_layout.alpha == 0f)
@ -459,9 +446,10 @@ class LibraryController(
}else { }else {
val position = if (freshStart) adapter.indexOf(activeCategory) else null
if (position != null) if (position != null)
(recycler.layoutManager as LinearLayoutManager) (recycler.layoutManager as LinearLayoutManager)
.scrollToPositionWithOffset(position, 0) .scrollToPositionWithOffset(position, (-30).dpToPx)
} }
adapter.isLongPressDragEnabled = canDrag() adapter.isLongPressDragEnabled = canDrag()
tabsVisibilityRelay.call(false) tabsVisibilityRelay.call(false)
@ -476,10 +464,10 @@ class LibraryController(
updateScroll = false updateScroll = false
return@IgnoreFirstSpinnerListener return@IgnoreFirstSpinnerListener
} }
val headerPosition = adapter.indexOf(pos - 1) + 1 val headerPosition = adapter.indexOf(pos - 1)
if (headerPosition > -1) { if (headerPosition > -1) {
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset( (recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
headerPosition, 0 headerPosition, (-30).dpToPx
) )
} }
} }
@ -598,45 +586,9 @@ class LibraryController(
else { else {
val position = val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() (recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
// if switching from list to grid libraryLayout = preferences.libraryLayout().getOrDefault()
if (recycler is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() == 0 recycler.adapter = adapter
|| recycler !is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() > 0) { (recycler as? AutofitRecyclerView)?.spanCount = if (libraryLayout == 0) 1 else mangaPerRow
destroyActionModeIfNeeded()
recycler_layout.removeView(recycler)
recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
(recycler_layout.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
layoutManager = LinearLayoutManager(context)
}
} else {
(recycler_layout.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
spanCount = mangaPerRow
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val item = this@LibraryController.adapter.getItem(position)
return if (item is LibraryHeaderItem) manager.spanCount else 1
}
})
}
}
recycler.setHasFixedSize(true)
adapter = LibraryCategoryAdapter(this)
recycler.adapter = adapter
recycler.addOnScrollListener(scrollListener)
adapter.isLongPressDragEnabled = canDrag()
recycler_layout.addView(recycler)
adapter.setItems(presenter.getList())
val config = resources?.configuration
val phoneLandscape = (config?.orientation == Configuration.ORIENTATION_LANDSCAPE &&
(config.screenLayout.and(Configuration.SCREENLAYOUT_SIZE_MASK)) <
Configuration.SCREENLAYOUT_SIZE_LARGE)
if (!usePager && !phoneLandscape) {
val height = recycler.resources.getDimensionPixelSize(R.dimen
.rounder_radius) + 4.dpToPx
recycler.updatePaddingRelative(bottom = height)
}
} else {
recycler.adapter = adapter
}
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, 0) (recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, 0)
} }
@ -924,19 +876,17 @@ class LibraryController(
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }
/// Method for single list
override fun startReading(position: Int) { override fun startReading(position: Int) {
val activity = activity ?: return
val manga = (adapter.getItem(position) as? LibraryItem)?.manga ?: return
if (adapter.mode == SelectableAdapter.Mode.MULTI) { if (adapter.mode == SelectableAdapter.Mode.MULTI) {
toggleSelection(position) toggleSelection(position)
return return
} }
val chapter = presenter.getFirstUnread(manga) ?: return val manga = (adapter.getItem(position) as? LibraryItem)?.manga ?: return
val intent = ReaderActivity.newIntent(activity, manga, chapter) startReading(manga)
destroyActionModeIfNeeded()
startActivity(intent)
} }
/// Method for the category view
fun startReading(manga: Manga) { fun startReading(manga: Manga) {
val activity = activity ?: return val activity = activity ?: return
val chapter = presenter.getFirstUnread(manga) ?: return val chapter = presenter.getFirstUnread(manga) ?: return
@ -1057,7 +1007,6 @@ class LibraryController(
} }
} }
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean { override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
if (adapter.selectedItemCount > 1) if (adapter.selectedItemCount > 1)
return false return false
@ -1089,47 +1038,3 @@ class LibraryController(
return "" return ""
} }
} }
object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
val topInset = insets.systemWindowInsetTop
v.setPadding(0,topInset,0,0)
if (v.layoutParams.height != topInset) {
v.layoutParams.height = topInset
v.requestLayout()
}
return insets
}
}
class SpinnerAdapter(context: Context, layoutId: Int, val array: Array<String>) :
ArrayAdapter<String>
(context, layoutId, array)
class ReSpinner : Spinner {
constructor(context: Context?) : super(context) {}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
context, attrs, defStyle
)
override fun setSelection(position: Int, animate: Boolean) {
val sameSelected = position == selectedItemPosition
super.setSelection(position, animate)
if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
onItemSelectedListener?.onItemSelected(
this, selectedView, position, selectedItemId
)
}
}
override fun setSelection(position: Int) {
val sameSelected = position == selectedItemPosition
super.setSelection(position)
if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
onItemSelectedListener?.onItemSelected(
this, selectedView, position, selectedItemId
)
}
}
}

View File

@ -90,7 +90,6 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
} }
) )
when { when {
item.category.id == -1 -> { item.category.id == -1 -> {
updateButton.invisible() updateButton.invisible()

View File

@ -39,32 +39,42 @@ class LibraryItem(val manga: LibraryManga,
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder {
val parent = adapter.recyclerView val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView) { return if (parent is AutofitRecyclerView) {
val fixedSize = libraryLayout.getOrDefault() == 1 val libraryLayout = libraryLayout.getOrDefault()
view.apply { if (libraryLayout == 0) {
val coverHeight = (parent.itemWidth / 3f * 4f).toInt() LibraryListHolder(view, adapter as LibraryCategoryAdapter)
if (fixedSize) { }
constraint_layout.layoutParams = FrameLayout.LayoutParams( else {
ViewGroup.LayoutParams.MATCH_PARENT, view.apply {
ViewGroup.LayoutParams.WRAP_CONTENT val coverHeight = (parent.itemWidth / 3f * 4f).toInt()
) if (libraryLayout == 1) {
val marginParams = card.layoutParams as ConstraintLayout.LayoutParams constraint_layout.layoutParams = FrameLayout.LayoutParams(
marginParams.bottomMargin = 6.dpToPx ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
card.layoutParams = marginParams )
cover_thumbnail.maxHeight = Integer.MAX_VALUE val marginParams = card.layoutParams as ConstraintLayout.LayoutParams
constraint_layout.minHeight = 0 marginParams.bottomMargin = 6.dpToPx
cover_thumbnail.adjustViewBounds = false card.layoutParams = marginParams
cover_thumbnail.layoutParams = cover_thumbnail.maxHeight = Integer.MAX_VALUE
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, coverHeight) constraint_layout.minHeight = 0
} cover_thumbnail.adjustViewBounds = false
else { cover_thumbnail.layoutParams = FrameLayout.LayoutParams(
constraint_layout.minHeight = coverHeight ViewGroup.LayoutParams.MATCH_PARENT,
cover_thumbnail.maxHeight = (parent.itemWidth / 3f * 6f).toInt() coverHeight
constraint_layout.background = ContextCompat.getDrawable(context, )
R.drawable.library_item_selector) } else if (libraryLayout == 2) {
} constraint_layout.minHeight = coverHeight
cover_thumbnail.maxHeight = (parent.itemWidth / 3f * 6f).toInt()
constraint_layout.background = ContextCompat.getDrawable(
context, R.drawable.library_item_selector
)
}
}
LibraryGridHolder(
view,
adapter as LibraryCategoryAdapter,
parent.itemWidth,
libraryLayout == 1
)
} }
LibraryGridHolder(view, adapter as LibraryCategoryAdapter, parent.itemWidth, fixedSize)
} else { } else {
LibraryListHolder(view, adapter as LibraryCategoryAdapter) LibraryListHolder(view, adapter as LibraryCategoryAdapter)
} }

View File

@ -0,0 +1,38 @@
package eu.kanade.tachiyomi.ui.library
import android.content.Context
import android.util.AttributeSet
import android.widget.ArrayAdapter
import android.widget.Spinner
class ReSpinner : Spinner {
constructor(context: Context?) : super(context) {}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
context, attrs, defStyle
)
override fun setSelection(position: Int, animate: Boolean) {
val sameSelected = position == selectedItemPosition
super.setSelection(position, animate)
if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
onItemSelectedListener?.onItemSelected(
this, selectedView, position, selectedItemId
)
}
}
override fun setSelection(position: Int) {
val sameSelected = position == selectedItemPosition
super.setSelection(position)
if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
onItemSelectedListener?.onItemSelected(
this, selectedView, position, selectedItemId
)
}
}
}
class SpinnerAdapter(context: Context, layoutId: Int, val array: Array<String>) :
ArrayAdapter<String>
(context, layoutId, array)

View File

@ -6,11 +6,8 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.WindowManager
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.internal.main.DialogLayout
import com.bluelinelabs.conductor.Router
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.ObjectKey import com.bumptech.glide.signature.ObjectKey
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -60,7 +57,7 @@ class EditMangaDialog : DialogController {
positiveButton(R.string.action_save) { onPositiveButtonClick() } positiveButton(R.string.action_save) { onPositiveButtonClick() }
} }
dialogView = dialog.view dialogView = dialog.view
onViewCreated(dialog.view, savedViewState) onViewCreated(dialog.view)
dialog.setOnShowListener { dialog.setOnShowListener {
val dView = (it as? MaterialDialog)?.view val dView = (it as? MaterialDialog)?.view
dView?.contentLayout?.scrollView?.scrollTo(0, 0) dView?.contentLayout?.scrollView?.scrollTo(0, 0)
@ -68,7 +65,7 @@ class EditMangaDialog : DialogController {
return dialog return dialog
} }
fun onViewCreated(view: View, savedState: Bundle?) { fun onViewCreated(view: View) {
GlideApp.with(view.context) GlideApp.with(view.context)
.asDrawable() .asDrawable()
.load(manga) .load(manga)

View File

@ -15,7 +15,6 @@ import android.view.ViewGroup
import android.view.WindowInsets import android.view.WindowInsets
import android.widget.TextView import android.widget.TextView
import androidx.annotation.Px import androidx.annotation.Px
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
@ -161,6 +160,18 @@ object RecyclerWindowInsetsListener : View.OnApplyWindowInsetsListener {
} }
} }
object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
val topInset = insets.systemWindowInsetTop
v.setPadding(0,topInset,0,0)
if (v.layoutParams.height != topInset) {
v.layoutParams.height = topInset
v.requestLayout()
}
return insets
}
}
fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) { fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) {
// Create a snapshot of the view's padding state // Create a snapshot of the view's padding state
if (MainActivity.usingBottomNav) return if (MainActivity.usingBottomNav) return

View File

@ -63,7 +63,7 @@
android:id="@+id/side_layout" android:id="@+id/side_layout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="6dp" android:layout_marginTop="16dp"
android:paddingStart="23dp" android:paddingStart="23dp"
android:paddingEnd="20dp" android:paddingEnd="20dp"
android:baselineAligned="true" android:baselineAligned="true"
@ -74,7 +74,6 @@
android:id="@+id/sorting_layout" android:id="@+id/sorting_layout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:baselineAligned="false" android:baselineAligned="false"
android:gravity="center|start" android:gravity="center|start"