Fix grid size computing
This commit is contained in:
@@ -9,6 +9,7 @@ import androidx.appcompat.widget.PopupMenu
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.core.ui.titleRes
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
@@ -48,26 +49,26 @@ class FavouritesListFragment : MangaListFragment(), PopupMenu.OnMenuItemClickLis
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_favourites, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
menu.findItem(R.id.action_save)?.isVisible = selectedItems.none {
|
||||
it.source == MangaSource.LOCAL
|
||||
}
|
||||
return super.onPrepareActionMode(mode, menu)
|
||||
return super.onPrepareActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_remove -> {
|
||||
viewModel.removeFromFavourites(selectedItemsIds)
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
else -> super.onActionItemClicked(mode, item)
|
||||
else -> super.onActionItemClicked(controller, mode, item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.appcompat.view.ActionMode
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
@@ -27,26 +28,26 @@ class HistoryListFragment : MangaListFragment() {
|
||||
|
||||
override fun onScrolledToEnd() = Unit
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_history, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
menu.findItem(R.id.action_save)?.isVisible = selectedItems.none {
|
||||
it.source == MangaSource.LOCAL
|
||||
}
|
||||
return super.onPrepareActionMode(mode, menu)
|
||||
return super.onPrepareActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_remove -> {
|
||||
viewModel.removeFromHistory(selectedItemsIds)
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
else -> super.onActionItemClicked(mode, item)
|
||||
else -> super.onActionItemClicked(controller, mode, item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,13 +53,13 @@ abstract class MangaListFragment :
|
||||
PaginationScrollListener.Callback,
|
||||
MangaListListener,
|
||||
SwipeRefreshLayout.OnRefreshListener,
|
||||
ListSelectionController.Callback,
|
||||
ListSelectionController.Callback2,
|
||||
FastScroller.FastScrollListener {
|
||||
|
||||
private var listAdapter: MangaListAdapter? = null
|
||||
private var paginationListener: PaginationScrollListener? = null
|
||||
private var selectionController: ListSelectionController? = null
|
||||
private val spanResolver = MangaListSpanResolver()
|
||||
private var spanResolver: MangaListSpanResolver? = null
|
||||
private val spanSizeLookup = SpanSizeLookup()
|
||||
private val listCommitCallback = Runnable {
|
||||
spanSizeLookup.invalidateCache()
|
||||
@@ -82,6 +82,7 @@ abstract class MangaListFragment :
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
listAdapter = onCreateAdapter()
|
||||
spanResolver = MangaListSpanResolver(view.resources)
|
||||
selectionController = ListSelectionController(
|
||||
activity = requireActivity(),
|
||||
decoration = MangaSelectionDecoration(view.context),
|
||||
@@ -116,6 +117,7 @@ abstract class MangaListFragment :
|
||||
listAdapter = null
|
||||
paginationListener = null
|
||||
selectionController = null
|
||||
spanResolver = null
|
||||
spanSizeLookup.invalidateCache()
|
||||
super.onDestroyView()
|
||||
}
|
||||
@@ -230,7 +232,7 @@ abstract class MangaListFragment :
|
||||
|
||||
private fun onGridScaleChanged(scale: Float) {
|
||||
spanSizeLookup.invalidateCache()
|
||||
spanResolver.setGridSize(scale, binding.recyclerView)
|
||||
spanResolver?.setGridSize(scale, binding.recyclerView)
|
||||
}
|
||||
|
||||
private fun onListModeChanged(mode: ListMode) {
|
||||
@@ -255,7 +257,7 @@ abstract class MangaListFragment :
|
||||
addItemDecoration(SpacingItemDecoration(spacing))
|
||||
}
|
||||
ListMode.GRID -> {
|
||||
layoutManager = FitHeightGridLayoutManager(context, spanResolver.spanCount).also {
|
||||
layoutManager = FitHeightGridLayoutManager(context, checkNotNull(spanResolver).spanCount).also {
|
||||
it.spanSizeLookup = spanSizeLookup
|
||||
}
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.grid_spacing)
|
||||
@@ -268,17 +270,11 @@ abstract class MangaListFragment :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
return menu.isNotEmpty()
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.title = selectionController?.count?.toString()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_select_all -> {
|
||||
val ids = listAdapter?.items?.mapNotNull {
|
||||
@@ -306,7 +302,7 @@ abstract class MangaListFragment :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSelectionChanged(count: Int) {
|
||||
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
|
||||
binding.recyclerView.invalidateItemDecorations()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
package org.koitharu.kotatsu.list.ui
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.koitharu.kotatsu.R
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
import org.koitharu.kotatsu.R
|
||||
|
||||
class MangaListSpanResolver : View.OnLayoutChangeListener {
|
||||
class MangaListSpanResolver(
|
||||
resources: Resources,
|
||||
) : View.OnLayoutChangeListener {
|
||||
|
||||
var spanCount = 3
|
||||
private set
|
||||
|
||||
private var gridWidth = -1f
|
||||
private val gridWidth = resources.getDimension(R.dimen.preferred_grid_width)
|
||||
private val spacing = resources.getDimension(R.dimen.grid_spacing)
|
||||
private var cellWidth = -1f
|
||||
|
||||
override fun onLayoutChange(
|
||||
@@ -24,15 +28,12 @@ class MangaListSpanResolver : View.OnLayoutChangeListener {
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int
|
||||
oldBottom: Int,
|
||||
) {
|
||||
if (cellWidth <= 0f) {
|
||||
return
|
||||
}
|
||||
val rv = v as? RecyclerView ?: return
|
||||
if (gridWidth < 0f) {
|
||||
gridWidth = rv.resources.getDimension(R.dimen.preferred_grid_width)
|
||||
}
|
||||
val width = abs(right - left)
|
||||
if (width == 0) {
|
||||
return
|
||||
@@ -41,17 +42,13 @@ class MangaListSpanResolver : View.OnLayoutChangeListener {
|
||||
(rv.layoutManager as? GridLayoutManager)?.spanCount = spanCount
|
||||
}
|
||||
|
||||
fun setGridSize(scaleFactor: Float, rv: RecyclerView?) {
|
||||
if (gridWidth < 0f) {
|
||||
gridWidth = (rv ?: return).resources.getDimension(R.dimen.preferred_grid_width)
|
||||
}
|
||||
cellWidth = gridWidth * scaleFactor
|
||||
if (rv != null) {
|
||||
val width = rv.width
|
||||
if (width != 0) {
|
||||
resolveGridSpanCount(width)
|
||||
(rv.layoutManager as? GridLayoutManager)?.spanCount = spanCount
|
||||
}
|
||||
fun setGridSize(scaleFactor: Float, rv: RecyclerView) {
|
||||
cellWidth = (gridWidth * scaleFactor) + spacing
|
||||
val lm = rv.layoutManager as? GridLayoutManager ?: return
|
||||
val innerWidth = lm.width - lm.paddingEnd - lm.paddingStart
|
||||
if (innerWidth > 0) {
|
||||
resolveGridSpanCount(innerWidth)
|
||||
lm.spanCount = spanCount
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +56,4 @@ class MangaListSpanResolver : View.OnLayoutChangeListener {
|
||||
val estimatedCount = (width / cellWidth).roundToInt()
|
||||
spanCount = estimatedCount.coerceAtLeast(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.utils.ShareHelper
|
||||
@@ -27,7 +28,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
override val viewModel by viewModel<LocalListViewModel>()
|
||||
private val importCall = registerForActivityResult(
|
||||
ActivityResultContracts.OpenMultipleDocuments(),
|
||||
this
|
||||
this,
|
||||
)
|
||||
private var importSnackbar: Snackbar? = null
|
||||
private val downloadReceiver = object : BroadcastReceiver() {
|
||||
@@ -42,7 +43,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
super.onAttach(context)
|
||||
context.registerReceiver(
|
||||
downloadReceiver,
|
||||
IntentFilter(DownloadService.ACTION_DOWNLOAD_COMPLETE)
|
||||
IntentFilter(DownloadService.ACTION_DOWNLOAD_COMPLETE),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
R.string.operation_not_supported,
|
||||
Snackbar.LENGTH_SHORT
|
||||
Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@@ -83,12 +84,12 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
viewModel.importFiles(result)
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_local, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_remove -> {
|
||||
showDeletionConfirm(selectedItemsIds, mode)
|
||||
@@ -100,7 +101,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
else -> super.onActionItemClicked(mode, item)
|
||||
else -> super.onActionItemClicked(controller, mode, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,4 +144,4 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback<List<@JvmS
|
||||
|
||||
fun newInstance() = LocalListFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class PagesThumbnailsSheet :
|
||||
OnListItemClickListener<MangaPage> {
|
||||
|
||||
private lateinit var thumbnails: List<PageThumbnail>
|
||||
private val spanResolver = MangaListSpanResolver()
|
||||
private var spanResolver: MangaListSpanResolver? = null
|
||||
private var currentPageIndex = -1
|
||||
private var pageLoader: PageLoader? = null
|
||||
|
||||
@@ -51,7 +51,7 @@ class PagesThumbnailsSheet :
|
||||
number = i + 1,
|
||||
isCurrent = i == currentPageIndex,
|
||||
repository = repository,
|
||||
page = x
|
||||
page = x,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -78,17 +78,17 @@ class PagesThumbnailsSheet :
|
||||
|
||||
with(binding.recyclerView) {
|
||||
addItemDecoration(
|
||||
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing))
|
||||
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)),
|
||||
)
|
||||
adapter = PageThumbnailAdapter(
|
||||
dataSet = thumbnails,
|
||||
coil = get(),
|
||||
scope = viewLifecycleScope,
|
||||
loader = getPageLoader(),
|
||||
clickListener = this@PagesThumbnailsSheet
|
||||
clickListener = this@PagesThumbnailsSheet,
|
||||
)
|
||||
addOnLayoutChangeListener(spanResolver)
|
||||
spanResolver.setGridSize(get<AppSettings>().gridSize / 100f, this)
|
||||
spanResolver?.setGridSize(get<AppSettings>().gridSize / 100f, this)
|
||||
if (currentPageIndex > 0) {
|
||||
val offset = resources.getDimensionPixelOffset(R.dimen.preferred_grid_width)
|
||||
(layoutManager as GridLayoutManager).scrollToPositionWithOffset(currentPageIndex, offset)
|
||||
@@ -98,6 +98,7 @@ class PagesThumbnailsSheet :
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
spanResolver = null
|
||||
pageLoader?.close()
|
||||
pageLoader = null
|
||||
}
|
||||
@@ -124,7 +125,7 @@ class PagesThumbnailsSheet :
|
||||
toolbar.subtitle = resources.getQuantityString(
|
||||
R.plurals.pages,
|
||||
thumbnails.size,
|
||||
thumbnails.size
|
||||
thumbnails.size,
|
||||
)
|
||||
} else {
|
||||
toolbar.subtitle = null
|
||||
@@ -147,4 +148,4 @@ class PagesThumbnailsSheet :
|
||||
putInt(ARG_CURRENT, currentPage)
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.core.view.MenuProvider
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.list.ui.filter.FilterBottomSheet
|
||||
import org.koitharu.kotatsu.main.ui.AppBarOwner
|
||||
@@ -38,9 +39,9 @@ class RemoteListFragment : MangaListFragment() {
|
||||
viewModel.loadNextPage()
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_remote, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
override fun onFilterClick(view: View?) {
|
||||
@@ -51,7 +52,9 @@ class RemoteListFragment : MangaListFragment() {
|
||||
viewModel.resetFilter()
|
||||
}
|
||||
|
||||
private inner class RemoteListMenuProvider : MenuProvider, SearchView.OnQueryTextListener,
|
||||
private inner class RemoteListMenuProvider :
|
||||
MenuProvider,
|
||||
SearchView.OnQueryTextListener,
|
||||
MenuItem.OnActionExpandListener {
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.appcompat.view.ActionMode
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.utils.ext.serializableArgument
|
||||
@@ -24,9 +25,9 @@ class SearchFragment : MangaListFragment() {
|
||||
viewModel.loadNextPage()
|
||||
}
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_remote, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -39,4 +40,4 @@ class SearchFragment : MangaListFragment() {
|
||||
putString(ARG_QUERY, query)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.core.view.MenuProvider
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||
@@ -26,9 +27,9 @@ class SuggestionsFragment : MangaListFragment() {
|
||||
|
||||
override fun onScrolledToEnd() = Unit
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.mode_remote, menu)
|
||||
return super.onCreateActionMode(mode, menu)
|
||||
return super.onCreateActionMode(controller, mode, menu)
|
||||
}
|
||||
|
||||
private inner class SuggestionMenuProvider : MenuProvider {
|
||||
@@ -59,4 +60,4 @@ class SuggestionsFragment : MangaListFragment() {
|
||||
|
||||
fun newInstance() = SuggestionsFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user