Unify list spacing approach
This commit is contained in:
@@ -7,6 +7,7 @@ import org.koitharu.kotatsu.bookmarks.domain.Bookmark
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD
|
||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||
@@ -19,10 +20,9 @@ class BookmarksAdapter(
|
||||
) : BaseListAdapter<ListModel>(), FastScroller.SectionIndexer {
|
||||
|
||||
init {
|
||||
delegatesManager
|
||||
.addDelegate(ITEM_TYPE_THUMBNAIL, bookmarkLargeAD(coil, lifecycleOwner, clickListener))
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(null))
|
||||
.addDelegate(ITEM_LOADING, loadingFooterAD())
|
||||
addDelegate(ListItemType.PAGE_THUMB, bookmarkLargeAD(coil, lifecycleOwner, clickListener))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(null))
|
||||
addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
|
||||
}
|
||||
|
||||
override fun getSectionText(context: Context, position: Int): CharSequence? {
|
||||
@@ -35,11 +35,4 @@ class BookmarksAdapter(
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_THUMBNAIL = 0
|
||||
const val ITEM_TYPE_HEADER = 1
|
||||
const val ITEM_LOADING = 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetBehavior
|
||||
import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetCallback
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
@@ -28,13 +27,14 @@ import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.databinding.SheetPagesBinding
|
||||
import org.koitharu.kotatsu.list.ui.MangaListSpanResolver
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity.IntentBuilder
|
||||
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
||||
import org.koitharu.kotatsu.reader.ui.thumbnails.OnPageSelectListener
|
||||
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
|
||||
import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@@ -75,9 +75,7 @@ class BookmarksSheet :
|
||||
)
|
||||
viewBinding?.headerBar?.setTitle(R.string.bookmarks)
|
||||
with(binding.recyclerView) {
|
||||
addItemDecoration(
|
||||
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)),
|
||||
)
|
||||
addItemDecoration(TypedListSpacingDecoration(context))
|
||||
adapter = bookmarksAdapter
|
||||
addOnLayoutChangeListener(spanResolver)
|
||||
spanResolver?.setGridSize(settings.gridSize / 100f, this)
|
||||
@@ -145,7 +143,7 @@ class BookmarksSheet :
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
val total = (viewBinding?.recyclerView?.layoutManager as? GridLayoutManager)?.spanCount ?: return 1
|
||||
return when (bookmarksAdapter?.getItemViewType(position)) {
|
||||
PageThumbnailAdapter.ITEM_TYPE_THUMBNAIL -> 1
|
||||
ListItemType.PAGE_THUMB.ordinal -> 1
|
||||
else -> total
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import androidx.activity.OnBackPressedDispatcher
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.dialog.AppBottomSheetDialog
|
||||
import org.koitharu.kotatsu.core.util.ext.findActivity
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplaySize
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@Deprecated(
|
||||
"Use BaseAdaptiveSheet",
|
||||
replaceWith = ReplaceWith("BaseAdaptiveSheet<B>", "org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet"),
|
||||
)
|
||||
abstract class BaseBottomSheet<B : ViewBinding> : BottomSheetDialogFragment() {
|
||||
|
||||
var viewBinding: B? = null
|
||||
private set
|
||||
|
||||
@Deprecated("", ReplaceWith("requireViewBinding()"))
|
||||
protected val binding: B
|
||||
get() = requireViewBinding()
|
||||
|
||||
protected val behavior: BottomSheetBehavior<*>?
|
||||
get() = (dialog as? BottomSheetDialog)?.behavior
|
||||
|
||||
val isExpanded: Boolean
|
||||
get() = behavior?.state == BottomSheetBehavior.STATE_EXPANDED
|
||||
|
||||
val onBackPressedDispatcher: OnBackPressedDispatcher
|
||||
get() = (requireDialog() as AppBottomSheetDialog).onBackPressedDispatcher
|
||||
|
||||
final override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
val binding = onCreateViewBinding(inflater, container)
|
||||
viewBinding = binding
|
||||
return binding.root
|
||||
}
|
||||
|
||||
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val binding = requireViewBinding()
|
||||
// Enforce max width for tablets
|
||||
val width = resources.getDimensionPixelSize(R.dimen.bottom_sheet_width)
|
||||
if (width > 0) {
|
||||
behavior?.maxWidth = width
|
||||
}
|
||||
// Set peek height to 40% display height
|
||||
binding.root.context.findActivity()?.getDisplaySize()?.let {
|
||||
behavior?.peekHeight = (it.height() * 0.4).toInt()
|
||||
}
|
||||
onViewBindingCreated(binding, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
viewBinding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return AppBottomSheetDialog(requireContext(), theme)
|
||||
}
|
||||
|
||||
fun addBottomSheetCallback(callback: BottomSheetBehavior.BottomSheetCallback) {
|
||||
val b = behavior ?: return
|
||||
b.addBottomSheetCallback(callback)
|
||||
val rootView = dialog?.findViewById<View>(materialR.id.design_bottom_sheet)
|
||||
if (rootView != null) {
|
||||
callback.onStateChanged(rootView, b.state)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): B
|
||||
|
||||
protected open fun onViewBindingCreated(binding: B, savedInstanceState: Bundle?) = Unit
|
||||
|
||||
protected fun setExpanded(isExpanded: Boolean, isLocked: Boolean) {
|
||||
val b = behavior ?: return
|
||||
if (isExpanded) {
|
||||
b.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
b.isFitToContents = !isExpanded
|
||||
val rootView = dialog?.findViewById<View>(materialR.id.design_bottom_sheet)
|
||||
rootView?.updateLayoutParams {
|
||||
height = if (isExpanded) LayoutParams.MATCH_PARENT else LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
b.isDraggable = !isLocked
|
||||
}
|
||||
|
||||
fun requireViewBinding(): B = checkNotNull(viewBinding) {
|
||||
"Fragment $this did not return a ViewBinding from onCreateView() or this was called before onCreateView()."
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import kotlinx.coroutines.asExecutor
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import org.koitharu.kotatsu.core.util.ContinuationResumeRunnable
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
@@ -25,6 +26,10 @@ open class BaseListAdapter<T : ListModel>(
|
||||
setItems(value, ContinuationResumeRunnable(cont))
|
||||
}
|
||||
|
||||
fun addDelegate(type: ListItemType, delegate: AdapterDelegate<List<T>>) {
|
||||
delegatesManager.addDelegate(type.ordinal, delegate)
|
||||
}
|
||||
|
||||
fun addListListener(listListener: ListListener<T>) {
|
||||
differ.addListListener(listListener)
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.ui.list.decor
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.util.SparseIntArray
|
||||
import android.view.View
|
||||
import androidx.core.util.getOrDefault
|
||||
import androidx.core.util.set
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class TypedSpacingItemDecoration(
|
||||
vararg spacingMapping: Pair<Int, Int>,
|
||||
private val fallbackSpacing: Int = 0,
|
||||
) : RecyclerView.ItemDecoration() {
|
||||
|
||||
private val mapping = SparseIntArray(spacingMapping.size)
|
||||
|
||||
init {
|
||||
spacingMapping.forEach { (k, v) -> mapping[k] = v }
|
||||
}
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val itemType = parent.getChildViewHolder(view)?.itemViewType
|
||||
val spacing = if (itemType == null) {
|
||||
fallbackSpacing
|
||||
} else {
|
||||
mapping.getOrDefault(itemType, fallbackSpacing)
|
||||
}
|
||||
outRect.set(spacing, spacing, spacing, spacing)
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,13 @@ import kotlinx.coroutines.flow.FlowCollector
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.databinding.ActivityDownloadsBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.download.ui.worker.PausingReceiver
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -46,7 +46,7 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
|
||||
listSpacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
val downloadsAdapter = DownloadsAdapter(this, coil, this)
|
||||
val decoration = SpacingItemDecoration(listSpacing)
|
||||
val decoration = TypedListSpacingDecoration(this)
|
||||
selectionController = ListSelectionController(
|
||||
activity = this,
|
||||
decoration = DownloadsSelectionDecoration(this),
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.download.ui.list
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD
|
||||
@@ -15,13 +16,9 @@ class DownloadsAdapter(
|
||||
) : BaseListAdapter<ListModel>() {
|
||||
|
||||
init {
|
||||
delegatesManager.addDelegate(ITEM_TYPE_DOWNLOAD, downloadItemAD(lifecycleOwner, coil, listener))
|
||||
.addDelegate(loadingStateAD())
|
||||
.addDelegate(emptyStateListAD(coil, lifecycleOwner, null))
|
||||
.addDelegate(listHeaderAD(null))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITEM_TYPE_DOWNLOAD = 0
|
||||
addDelegate(ListItemType.DOWNLOAD, downloadItemAD(lifecycleOwner, coil, listener))
|
||||
addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
|
||||
addDelegate(ListItemType.STATE_EMPTY, emptyStateListAD(coil, lifecycleOwner, null))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(null))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.explore.ui
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
|
||||
import org.koitharu.kotatsu.explore.ui.adapter.ExploreAdapter
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
|
||||
class ExploreGridSpanSizeLookup(
|
||||
private val adapter: ExploreAdapter,
|
||||
@@ -11,6 +12,6 @@ class ExploreGridSpanSizeLookup(
|
||||
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
val itemType = adapter.getItemViewType(position)
|
||||
return if (itemType == ExploreAdapter.ITEM_TYPE_SOURCE_GRID) 1 else layoutManager.spanCount
|
||||
return if (itemType == ListItemType.EXPLORE_SOURCE_GRID.ordinal) 1 else layoutManager.spanCount
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.widgets.TipView
|
||||
import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.emptyHintAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD
|
||||
@@ -23,29 +24,16 @@ class ExploreAdapter(
|
||||
) : BaseListAdapter<ListModel>() {
|
||||
|
||||
init {
|
||||
delegatesManager
|
||||
.addDelegate(ITEM_TYPE_BUTTONS, exploreButtonsAD(listener))
|
||||
.addDelegate(
|
||||
ITEM_TYPE_RECOMMENDATION,
|
||||
exploreRecommendationItemAD(coil, listener, mangaClickListener, lifecycleOwner),
|
||||
)
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(listener))
|
||||
.addDelegate(ITEM_TYPE_SOURCE_LIST, exploreSourceListItemAD(coil, clickListener, lifecycleOwner))
|
||||
.addDelegate(ITEM_TYPE_SOURCE_GRID, exploreSourceGridItemAD(coil, clickListener, lifecycleOwner))
|
||||
.addDelegate(ITEM_TYPE_HINT, emptyHintAD(coil, lifecycleOwner, listener))
|
||||
.addDelegate(ITEM_TYPE_LOADING, loadingStateAD())
|
||||
.addDelegate(ITEM_TIP, tipAD(tipClickListener))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_BUTTONS = 0
|
||||
const val ITEM_TYPE_HEADER = 1
|
||||
const val ITEM_TYPE_SOURCE_LIST = 2
|
||||
const val ITEM_TYPE_SOURCE_GRID = 3
|
||||
const val ITEM_TYPE_HINT = 4
|
||||
const val ITEM_TYPE_LOADING = 5
|
||||
const val ITEM_TYPE_RECOMMENDATION = 6
|
||||
const val ITEM_TIP = 7
|
||||
addDelegate(ListItemType.EXPLORE_BUTTONS, exploreButtonsAD(listener))
|
||||
addDelegate(
|
||||
ListItemType.EXPLORE_SUGGESTION,
|
||||
exploreRecommendationItemAD(coil, listener, mangaClickListener, lifecycleOwner),
|
||||
)
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(listener))
|
||||
addDelegate(ListItemType.EXPLORE_SOURCE_LIST, exploreSourceListItemAD(coil, clickListener, lifecycleOwner))
|
||||
addDelegate(ListItemType.EXPLORE_SOURCE_GRID, exploreSourceGridItemAD(coil, clickListener, lifecycleOwner))
|
||||
addDelegate(ListItemType.HINT_EMPTY, emptyHintAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
|
||||
addDelegate(ListItemType.TIP, tipAD(tipClickListener))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.recyclerview.widget.AsyncListDiffer.ListListener
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.filter.ui.model.FilterItem
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD
|
||||
@@ -16,13 +17,12 @@ class FilterAdapter(
|
||||
) : BaseListAdapter<ListModel>(), FastScroller.SectionIndexer {
|
||||
|
||||
init {
|
||||
delegatesManager
|
||||
.addDelegate(ITEM_TYPE_SORT, filterSortDelegate(listener))
|
||||
.addDelegate(ITEM_TYPE_TAG, filterTagDelegate(listener))
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(listener))
|
||||
.addDelegate(loadingStateAD())
|
||||
.addDelegate(loadingFooterAD())
|
||||
.addDelegate(filterErrorDelegate())
|
||||
addDelegate(ListItemType.FILTER_SORT, filterSortDelegate(listener))
|
||||
addDelegate(ListItemType.FILTER_TAG, filterTagDelegate(listener))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(listener))
|
||||
addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
|
||||
addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
|
||||
addDelegate(ListItemType.FOOTER_ERROR, filterErrorDelegate())
|
||||
differ.addListListener(listListener)
|
||||
}
|
||||
|
||||
@@ -36,11 +36,4 @@ class FilterAdapter(
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_SORT = 0
|
||||
const val ITEM_TYPE_TAG = 1
|
||||
const val ITEM_TYPE_HEADER = 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.koitharu.kotatsu.filter.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.koitharu.kotatsu.R
|
||||
|
||||
class FilterItemDecoration(
|
||||
context: Context,
|
||||
) : RecyclerView.ItemDecoration() {
|
||||
|
||||
private val spacing = context.resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val itemType = parent.getChildViewHolder(view)?.itemViewType ?: -1
|
||||
if (itemType == FilterAdapter.ITEM_TYPE_HEADER) {
|
||||
outRect.set(spacing, 0, spacing, 0)
|
||||
} else {
|
||||
outRect.set(0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.databinding.SheetFilterBinding
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
|
||||
class FilterSheetFragment :
|
||||
@@ -32,7 +33,7 @@ class FilterSheetFragment :
|
||||
val adapter = FilterAdapter(filter, this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
filter.filterItems.observe(viewLifecycleOwner, adapter)
|
||||
binding.recyclerView.addItemDecoration(FilterItemDecoration(binding.root.context))
|
||||
binding.recyclerView.addItemDecoration(TypedListSpacingDecoration(binding.root.context))
|
||||
|
||||
if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
binding.recyclerView.scrollIndicators = 0
|
||||
|
||||
@@ -21,6 +21,7 @@ open class ListModelDiffCallback<T : ListModel> : DiffUtil.ItemCallback<T>() {
|
||||
|
||||
val PAYLOAD_CHECKED_CHANGED = Any()
|
||||
val PAYLOAD_NESTED_LIST_CHANGED = Any()
|
||||
val PAYLOAD_PROGRESS_CHANGED = Any()
|
||||
val PAYLOAD_ANYTHING_CHANGED = Any()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,10 @@ import org.koitharu.kotatsu.core.ui.list.FitHeightGridLayoutManager
|
||||
import org.koitharu.kotatsu.core.ui.list.FitHeightLinearLayoutManager
|
||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.core.ui.list.PaginationScrollListener
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
|
||||
import org.koitharu.kotatsu.core.util.ShareHelper
|
||||
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.core.util.ext.clearItemDecorations
|
||||
import org.koitharu.kotatsu.core.util.ext.measureHeight
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
@@ -45,9 +42,10 @@ import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesSheet
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter.Companion.ITEM_TYPE_MANGA_GRID
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
||||
@@ -106,6 +104,7 @@ abstract class MangaListFragment :
|
||||
setHasFixedSize(true)
|
||||
adapter = listAdapter
|
||||
checkNotNull(selectionController).attachToRecyclerView(binding.recyclerView)
|
||||
addItemDecoration(TypedListSpacingDecoration(context))
|
||||
addOnScrollListener(paginationListener!!)
|
||||
fastScroller.setFastScrollListener(this@MangaListFragment)
|
||||
}
|
||||
@@ -238,24 +237,17 @@ abstract class MangaListFragment :
|
||||
private fun onListModeChanged(mode: ListMode) {
|
||||
spanSizeLookup.invalidateCache()
|
||||
with(requireViewBinding().recyclerView) {
|
||||
clearItemDecorations()
|
||||
removeOnLayoutChangeListener(spanResolver)
|
||||
when (mode) {
|
||||
ListMode.LIST -> {
|
||||
layoutManager = FitHeightLinearLayoutManager(context)
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
val decoration = TypedSpacingItemDecoration(
|
||||
MangaListAdapter.ITEM_TYPE_MANGA_LIST to 0,
|
||||
fallbackSpacing = spacing,
|
||||
)
|
||||
addItemDecoration(decoration)
|
||||
updatePadding(left = 0, right = 0)
|
||||
}
|
||||
|
||||
ListMode.DETAILED_LIST -> {
|
||||
layoutManager = FitHeightLinearLayoutManager(context)
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
updatePadding(left = spacing, right = spacing)
|
||||
addItemDecoration(SpacingItemDecoration(spacing))
|
||||
}
|
||||
|
||||
ListMode.GRID -> {
|
||||
@@ -263,12 +255,10 @@ abstract class MangaListFragment :
|
||||
it.spanSizeLookup = spanSizeLookup
|
||||
}
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.grid_spacing)
|
||||
addItemDecoration(SpacingItemDecoration(spacing))
|
||||
updatePadding(left = spacing, right = spacing)
|
||||
addOnLayoutChangeListener(spanResolver)
|
||||
}
|
||||
}
|
||||
selectionController?.attachToRecyclerView(requireViewBinding().recyclerView)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +333,7 @@ abstract class MangaListFragment :
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
val total = (viewBinding?.recyclerView?.layoutManager as? GridLayoutManager)?.spanCount ?: return 1
|
||||
return when (listAdapter?.getItemViewType(position)) {
|
||||
ITEM_TYPE_MANGA_GRID -> 1
|
||||
ListItemType.MANGA_GRID.ordinal -> 1
|
||||
else -> total
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.koitharu.kotatsu.list.ui.adapter
|
||||
|
||||
enum class ListItemType {
|
||||
|
||||
FILTER_SORT,
|
||||
FILTER_TAG,
|
||||
HEADER,
|
||||
MANGA_LIST,
|
||||
MANGA_LIST_DETAILED,
|
||||
MANGA_GRID,
|
||||
FOOTER_LOADING,
|
||||
FOOTER_ERROR,
|
||||
STATE_LOADING,
|
||||
STATE_ERROR,
|
||||
STATE_EMPTY,
|
||||
EXPLORE_BUTTONS,
|
||||
EXPLORE_SOURCE_GRID,
|
||||
EXPLORE_SOURCE_LIST,
|
||||
EXPLORE_SUGGESTION,
|
||||
TIP,
|
||||
HINT_EMPTY,
|
||||
PAGE_THUMB,
|
||||
FEED,
|
||||
DOWNLOAD,
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.koitharu.kotatsu.core.util.ext.newImageRequest
|
||||
import org.koitharu.kotatsu.core.util.ext.source
|
||||
import org.koitharu.kotatsu.databinding.ItemMangaGridBinding
|
||||
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.list.ui.model.MangaGridModel
|
||||
import org.koitharu.kotatsu.list.ui.size.ItemSizeResolver
|
||||
@@ -39,7 +40,7 @@ fun mangaGridItemAD(
|
||||
|
||||
bind { payloads ->
|
||||
binding.textViewTitle.text = item.title
|
||||
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
||||
binding.progressView.setPercent(item.progress, ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED in payloads)
|
||||
binding.imageViewCover.newImageRequest(lifecycleOwner, item.coverUrl)?.run {
|
||||
size(CoverSizeResolver(binding.imageViewCover))
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
|
||||
@@ -12,30 +12,14 @@ open class MangaListAdapter(
|
||||
) : BaseListAdapter<ListModel>() {
|
||||
|
||||
init {
|
||||
delegatesManager
|
||||
.addDelegate(ITEM_TYPE_MANGA_LIST, mangaListItemAD(coil, lifecycleOwner, listener))
|
||||
.addDelegate(ITEM_TYPE_MANGA_LIST_DETAILED, mangaListDetailedItemAD(coil, lifecycleOwner, listener))
|
||||
.addDelegate(ITEM_TYPE_MANGA_GRID, mangaGridItemAD(coil, lifecycleOwner, null, listener))
|
||||
.addDelegate(ITEM_TYPE_LOADING_FOOTER, loadingFooterAD())
|
||||
.addDelegate(ITEM_TYPE_LOADING_STATE, loadingStateAD())
|
||||
.addDelegate(ITEM_TYPE_ERROR_STATE, errorStateListAD(listener))
|
||||
.addDelegate(ITEM_TYPE_ERROR_FOOTER, errorFooterAD(listener))
|
||||
.addDelegate(ITEM_TYPE_EMPTY, emptyStateListAD(coil, lifecycleOwner, listener))
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(listener))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_MANGA_LIST = 0
|
||||
const val ITEM_TYPE_MANGA_LIST_DETAILED = 1
|
||||
const val ITEM_TYPE_MANGA_GRID = 2
|
||||
const val ITEM_TYPE_LOADING_FOOTER = 3
|
||||
const val ITEM_TYPE_LOADING_STATE = 4
|
||||
const val ITEM_TYPE_ERROR_STATE = 6
|
||||
const val ITEM_TYPE_ERROR_FOOTER = 7
|
||||
const val ITEM_TYPE_EMPTY = 8
|
||||
const val ITEM_TYPE_HEADER = 9
|
||||
|
||||
val PAYLOAD_PROGRESS = Any()
|
||||
addDelegate(ListItemType.MANGA_LIST, mangaListItemAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.MANGA_LIST_DETAILED, mangaListDetailedItemAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.MANGA_GRID, mangaGridItemAD(coil, lifecycleOwner, null, listener))
|
||||
addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
|
||||
addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
|
||||
addDelegate(ListItemType.STATE_ERROR, errorStateListAD(listener))
|
||||
addDelegate(ListItemType.FOOTER_ERROR, errorFooterAD(listener))
|
||||
addDelegate(ListItemType.STATE_EMPTY, emptyStateListAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(listener))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.koitharu.kotatsu.core.util.ext.source
|
||||
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||
import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding
|
||||
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.list.ui.model.MangaListDetailedModel
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
@@ -52,7 +53,7 @@ fun mangaListDetailedItemAD(
|
||||
bind { payloads ->
|
||||
binding.textViewTitle.text = item.title
|
||||
binding.textViewSubtitle.textAndVisible = item.subtitle
|
||||
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
||||
binding.progressView.setPercent(item.progress, ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED in payloads)
|
||||
binding.imageViewCover.newImageRequest(lifecycleOwner, item.coverUrl)?.run {
|
||||
size(CoverSizeResolver(binding.imageViewCover))
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.koitharu.kotatsu.list.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
|
||||
import org.koitharu.kotatsu.R
|
||||
|
||||
class TypedListSpacingDecoration(
|
||||
context: Context,
|
||||
) : ItemDecoration() {
|
||||
|
||||
private val spacingList = context.resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
private val spacingGrid = context.resources.getDimensionPixelOffset(R.dimen.grid_spacing)
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val itemType = parent.getChildViewHolder(view)?.itemViewType?.let {
|
||||
ListItemType.values().getOrNull(it)
|
||||
}
|
||||
when (itemType) {
|
||||
ListItemType.FILTER_SORT,
|
||||
ListItemType.FILTER_TAG -> outRect.set(0)
|
||||
|
||||
ListItemType.HEADER -> outRect.set(spacingList, 0, spacingList, 0)
|
||||
ListItemType.MANGA_LIST -> outRect.set(0)
|
||||
ListItemType.DOWNLOAD,
|
||||
ListItemType.MANGA_LIST_DETAILED -> outRect.set(spacingList)
|
||||
|
||||
ListItemType.PAGE_THUMB,
|
||||
ListItemType.MANGA_GRID -> outRect.set(spacingGrid)
|
||||
|
||||
ListItemType.FOOTER_LOADING,
|
||||
ListItemType.FOOTER_ERROR,
|
||||
ListItemType.STATE_LOADING,
|
||||
ListItemType.STATE_ERROR,
|
||||
ListItemType.STATE_EMPTY,
|
||||
ListItemType.EXPLORE_BUTTONS,
|
||||
ListItemType.EXPLORE_SOURCE_GRID,
|
||||
ListItemType.EXPLORE_SOURCE_LIST,
|
||||
ListItemType.EXPLORE_SUGGESTION,
|
||||
null -> outRect.set(0)
|
||||
|
||||
ListItemType.TIP -> outRect.set(0) // TODO
|
||||
ListItemType.HINT_EMPTY -> outRect.set(0) // TODO
|
||||
ListItemType.FEED -> outRect.set(0) // TODO
|
||||
}
|
||||
}
|
||||
|
||||
private fun Rect.set(spacing: Int) = set(spacing, spacing, spacing, spacing)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.koitharu.kotatsu.list.ui.model
|
||||
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
|
||||
@@ -23,8 +23,8 @@ sealed class MangaItemModel : ListModel {
|
||||
override fun getChangePayload(previousState: ListModel): Any? {
|
||||
return when {
|
||||
previousState !is MangaItemModel -> super.getChangePayload(previousState)
|
||||
progress != previousState.progress -> MangaListAdapter.PAYLOAD_PROGRESS
|
||||
counter != previousState.counter -> Unit
|
||||
progress != previousState.progress -> ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED
|
||||
counter != previousState.counter -> ListModelDiffCallback.PAYLOAD_ANYTHING_CHANGED
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.list.BoundsScrollListener
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetBehavior
|
||||
import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetCallback
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
@@ -29,6 +28,8 @@ import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.databinding.SheetPagesBinding
|
||||
import org.koitharu.kotatsu.list.ui.MangaListSpanResolver
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity.IntentBuilder
|
||||
@@ -74,9 +75,7 @@ class PagesThumbnailsSheet :
|
||||
clickListener = this@PagesThumbnailsSheet,
|
||||
)
|
||||
with(binding.recyclerView) {
|
||||
addItemDecoration(
|
||||
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)),
|
||||
)
|
||||
addItemDecoration(TypedListSpacingDecoration(context))
|
||||
adapter = thumbnailsAdapter
|
||||
addOnLayoutChangeListener(spanResolver)
|
||||
spanResolver?.setGridSize(settings.gridSize / 100f, this)
|
||||
@@ -171,7 +170,7 @@ class PagesThumbnailsSheet :
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
val total = (viewBinding?.recyclerView?.layoutManager as? GridLayoutManager)?.spanCount ?: return 1
|
||||
return when (thumbnailsAdapter?.getItemViewType(position)) {
|
||||
PageThumbnailAdapter.ITEM_TYPE_THUMBNAIL -> 1
|
||||
ListItemType.PAGE_THUMB.ordinal -> 1
|
||||
else -> total
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import coil.ImageLoader
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD
|
||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||
@@ -19,9 +20,9 @@ class PageThumbnailAdapter(
|
||||
) : BaseListAdapter<ListModel>(), FastScroller.SectionIndexer {
|
||||
|
||||
init {
|
||||
delegatesManager.addDelegate(ITEM_TYPE_THUMBNAIL, pageThumbnailAD(coil, lifecycleOwner, clickListener))
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(null))
|
||||
.addDelegate(ITEM_LOADING, loadingFooterAD())
|
||||
addDelegate(ListItemType.PAGE_THUMB, pageThumbnailAD(coil, lifecycleOwner, clickListener))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(null))
|
||||
addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
|
||||
}
|
||||
|
||||
override fun getSectionText(context: Context, position: Int): CharSequence? {
|
||||
@@ -34,11 +35,4 @@ class PageThumbnailAdapter(
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_THUMBNAIL = 0
|
||||
const val ITEM_TYPE_HEADER = 1
|
||||
const val ITEM_LOADING = 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.util.ext.disposeImageRequest
|
||||
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
||||
import org.koitharu.kotatsu.core.util.ext.newImageRequest
|
||||
@@ -22,11 +21,11 @@ import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.databinding.ActivityScrobblerConfigBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
|
||||
import org.koitharu.kotatsu.scrobbling.common.ui.config.adapter.ScrobblingMangaAdapter
|
||||
import org.koitharu.kotatsu.tracker.ui.feed.adapter.FeedAdapter
|
||||
import javax.inject.Inject
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@@ -55,10 +54,7 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
paddingHorizontal = spacing
|
||||
paddingVertical = resources.getDimensionPixelOffset(R.dimen.grid_spacing_outer)
|
||||
val decoration = TypedSpacingItemDecoration(
|
||||
FeedAdapter.ITEM_TYPE_FEED to 0,
|
||||
fallbackSpacing = spacing,
|
||||
)
|
||||
val decoration = TypedListSpacingDecoration(context)
|
||||
addItemDecoration(decoration)
|
||||
}
|
||||
viewBinding.imageViewAvatar.setOnClickListener(this)
|
||||
|
||||
@@ -15,13 +15,13 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.core.ui.list.PaginationScrollListener
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.TypedSpacingItemDecoration
|
||||
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.databinding.FragmentFeedBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
|
||||
@@ -55,12 +55,7 @@ class FeedFragment :
|
||||
adapter = feedAdapter
|
||||
setHasFixedSize(true)
|
||||
addOnScrollListener(PaginationScrollListener(4, this@FeedFragment))
|
||||
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
val decoration = TypedSpacingItemDecoration(
|
||||
FeedAdapter.ITEM_TYPE_FEED to 0,
|
||||
fallbackSpacing = spacing,
|
||||
)
|
||||
addItemDecoration(decoration)
|
||||
addItemDecoration(TypedListSpacingDecoration(context))
|
||||
}
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(this)
|
||||
addMenuProvider(
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
|
||||
import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD
|
||||
import org.koitharu.kotatsu.list.ui.adapter.errorFooterAD
|
||||
@@ -22,13 +23,13 @@ class FeedAdapter(
|
||||
) : BaseListAdapter<ListModel>(), FastScroller.SectionIndexer {
|
||||
|
||||
init {
|
||||
delegatesManager.addDelegate(ITEM_TYPE_FEED, feedItemAD(coil, lifecycleOwner, listener))
|
||||
.addDelegate(ITEM_TYPE_LOADING_FOOTER, loadingFooterAD())
|
||||
.addDelegate(ITEM_TYPE_LOADING_STATE, loadingStateAD())
|
||||
.addDelegate(ITEM_TYPE_ERROR_FOOTER, errorFooterAD(listener))
|
||||
.addDelegate(ITEM_TYPE_ERROR_STATE, errorStateListAD(listener))
|
||||
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(listener))
|
||||
.addDelegate(ITEM_TYPE_EMPTY, emptyStateListAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.FEED, feedItemAD(coil, lifecycleOwner, listener))
|
||||
addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
|
||||
addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
|
||||
addDelegate(ListItemType.FOOTER_ERROR, errorFooterAD(listener))
|
||||
addDelegate(ListItemType.STATE_ERROR, errorStateListAD(listener))
|
||||
addDelegate(ListItemType.HEADER, listHeaderAD(listener))
|
||||
addDelegate(ListItemType.STATE_EMPTY, emptyStateListAD(coil, lifecycleOwner, listener))
|
||||
}
|
||||
|
||||
override fun getSectionText(context: Context, position: Int): CharSequence? {
|
||||
@@ -41,15 +42,4 @@ class FeedAdapter(
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_TYPE_FEED = 0
|
||||
const val ITEM_TYPE_LOADING_FOOTER = 1
|
||||
const val ITEM_TYPE_LOADING_STATE = 2
|
||||
const val ITEM_TYPE_ERROR_STATE = 3
|
||||
const val ITEM_TYPE_ERROR_FOOTER = 4
|
||||
const val ITEM_TYPE_EMPTY = 5
|
||||
const val ITEM_TYPE_HEADER = 6
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user