Unify list spacings

pull/453/head
Koitharu 3 years ago
parent d54d489494
commit c8e4842b6e
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -29,7 +29,6 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.ui.util.reverseAsync import org.koitharu.kotatsu.core.ui.util.reverseAsync
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.databinding.FragmentListSimpleBinding import org.koitharu.kotatsu.databinding.FragmentListSimpleBinding
import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.details.ui.DetailsActivity
import org.koitharu.kotatsu.list.ui.MangaListSpanResolver import org.koitharu.kotatsu.list.ui.MangaListSpanResolver
@ -84,7 +83,7 @@ class BookmarksFragment :
with(binding.recyclerView) { with(binding.recyclerView) {
setHasFixedSize(true) setHasFixedSize(true)
val spanResolver = MangaListSpanResolver(resources) val spanResolver = MangaListSpanResolver(resources)
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, false))
adapter = bookmarksAdapter adapter = bookmarksAdapter
addOnLayoutChangeListener(spanResolver) addOnLayoutChangeListener(spanResolver)
spanResolver.setGridSize(settings.gridSize / 100f, this) spanResolver.setGridSize(settings.gridSize / 100f, this)
@ -159,10 +158,11 @@ class BookmarksFragment :
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding( val rv = requireViewBinding().recyclerView
bottom = insets.bottom, rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
) )
requireViewBinding().recyclerView.fastScroller.updateLayoutParams<ViewGroup.MarginLayoutParams> { rv.fastScroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = insets.bottom bottomMargin = insets.bottom
} }
} }

@ -75,7 +75,7 @@ class BookmarksSheet :
) )
viewBinding?.headerBar?.setTitle(R.string.bookmarks) viewBinding?.headerBar?.setTitle(R.string.bookmarks)
with(binding.recyclerView) { with(binding.recyclerView) {
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, false))
adapter = bookmarksAdapter adapter = bookmarksAdapter
addOnLayoutChangeListener(spanResolver) addOnLayoutChangeListener(spanResolver)
spanResolver?.setGridSize(settings.gridSize / 100f, this) spanResolver?.setGridSize(settings.gridSize / 100f, this)

@ -7,7 +7,6 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.Px
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
@ -37,16 +36,12 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
private val viewModel by viewModels<DownloadsViewModel>() private val viewModel by viewModels<DownloadsViewModel>()
private lateinit var selectionController: ListSelectionController private lateinit var selectionController: ListSelectionController
@Px
private var listSpacing = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityDownloadsBinding.inflate(layoutInflater)) setContentView(ActivityDownloadsBinding.inflate(layoutInflater))
listSpacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
val downloadsAdapter = DownloadsAdapter(this, coil, this) val downloadsAdapter = DownloadsAdapter(this, coil, this)
val decoration = TypedListSpacingDecoration(this) val decoration = TypedListSpacingDecoration(this, false)
selectionController = ListSelectionController( selectionController = ListSelectionController(
activity = this, activity = this,
decoration = DownloadsSelectionDecoration(this), decoration = DownloadsSelectionDecoration(this),
@ -71,9 +66,10 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.recyclerView.updatePadding( val rv = viewBinding.recyclerView
left = insets.left + listSpacing, rv.updatePadding(
right = insets.right + listSpacing, left = insets.left + rv.paddingTop,
right = insets.right + rv.paddingTop,
bottom = insets.bottom, bottom = insets.bottom,
) )
viewBinding.toolbar.updatePadding( viewBinding.toolbar.updatePadding(

@ -74,7 +74,7 @@ class ExploreFragment :
adapter = exploreAdapter adapter = exploreAdapter
setHasFixedSize(true) setHasFixedSize(true)
SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach() SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach()
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, false))
} }
addMenuProvider(ExploreMenuProvider(binding.root.context, viewModel)) addMenuProvider(ExploreMenuProvider(binding.root.context, viewModel))
viewModel.content.observe(viewLifecycleOwner) { viewModel.content.observe(viewLifecycleOwner) {

@ -24,6 +24,7 @@ import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
import org.koitharu.kotatsu.favourites.ui.categories.adapter.CategoriesAdapter import org.koitharu.kotatsu.favourites.ui.categories.adapter.CategoriesAdapter
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.model.SortOrder
import javax.inject.Inject import javax.inject.Inject
@ -58,6 +59,7 @@ class FavouriteCategoriesActivity :
selectionController.attachToRecyclerView(viewBinding.recyclerView) selectionController.attachToRecyclerView(viewBinding.recyclerView)
viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.setHasFixedSize(true)
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, false))
viewBinding.fabAdd.setOnClickListener(this) viewBinding.fabAdd.setOnClickListener(this)
reorderHelper = ItemTouchHelper(ReorderHelperCallback()).apply { reorderHelper = ItemTouchHelper(ReorderHelperCallback()).apply {
@ -106,7 +108,7 @@ class FavouriteCategoriesActivity :
right = insets.right, right = insets.right,
) )
viewBinding.recyclerView.updatePadding( viewBinding.recyclerView.updatePadding(
bottom = insets.bottom, bottom = insets.bottom + viewBinding.recyclerView.paddingTop,
) )
} }

@ -4,6 +4,7 @@ import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader import coil.ImageLoader
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesListListener import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesListListener
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD
import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD
@ -17,8 +18,8 @@ class CategoriesAdapter(
) : BaseListAdapter<ListModel>() { ) : BaseListAdapter<ListModel>() {
init { init {
delegatesManager.addDelegate(categoryAD(coil, lifecycleOwner, onItemClickListener)) addDelegate(ListItemType.CATEGORY_LARGE ,categoryAD(coil, lifecycleOwner, onItemClickListener))
.addDelegate(emptyStateListAD(coil, lifecycleOwner, listListener)) addDelegate(ListItemType.STATE_EMPTY ,emptyStateListAD(coil, lifecycleOwner, listListener))
.addDelegate(loadingStateAD()) addDelegate(ListItemType.STATE_LOADING ,loadingStateAD())
} }
} }

@ -33,7 +33,7 @@ class FilterSheetFragment :
val adapter = FilterAdapter(filter, this) val adapter = FilterAdapter(filter, this)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
filter.filterItems.observe(viewLifecycleOwner, adapter) filter.filterItems.observe(viewLifecycleOwner, adapter)
binding.recyclerView.addItemDecoration(TypedListSpacingDecoration(binding.root.context)) binding.recyclerView.addItemDecoration(TypedListSpacingDecoration(binding.root.context, false))
if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.recyclerView.scrollIndicators = 0 binding.recyclerView.scrollIndicators = 0

@ -108,7 +108,7 @@ abstract class MangaListFragment :
setHasFixedSize(true) setHasFixedSize(true)
adapter = listAdapter adapter = listAdapter
checkNotNull(selectionController).attachToRecyclerView(binding.recyclerView) checkNotNull(selectionController).attachToRecyclerView(binding.recyclerView)
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, false))
addOnScrollListener(paginationListener!!) addOnScrollListener(paginationListener!!)
fastScroller.setFastScrollListener(this@MangaListFragment) fastScroller.setFastScrollListener(this@MangaListFragment)
} }
@ -247,21 +247,16 @@ abstract class MangaListFragment :
when (mode) { when (mode) {
ListMode.LIST -> { ListMode.LIST -> {
layoutManager = FitHeightLinearLayoutManager(context) layoutManager = FitHeightLinearLayoutManager(context)
updatePadding(left = 0, right = 0)
} }
ListMode.DETAILED_LIST -> { ListMode.DETAILED_LIST -> {
layoutManager = FitHeightLinearLayoutManager(context) layoutManager = FitHeightLinearLayoutManager(context)
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
updatePadding(left = spacing, right = spacing)
} }
ListMode.GRID -> { ListMode.GRID -> {
layoutManager = FitHeightGridLayoutManager(context, checkNotNull(spanResolver).spanCount).also { layoutManager = FitHeightGridLayoutManager(context, checkNotNull(spanResolver).spanCount).also {
it.spanSizeLookup = spanSizeLookup it.spanSizeLookup = spanSizeLookup
} }
val spacing = resources.getDimensionPixelOffset(R.dimen.grid_spacing)
updatePadding(left = spacing, right = spacing)
addOnLayoutChangeListener(spanResolver) addOnLayoutChangeListener(spanResolver)
} }
} }

@ -23,4 +23,6 @@ enum class ListItemType {
PAGE_THUMB, PAGE_THUMB,
FEED, FEED,
DOWNLOAD, DOWNLOAD,
CATEGORY_LARGE,
MANGA_SCROBBLING,
} }

@ -9,11 +9,12 @@ import org.koitharu.kotatsu.R
class TypedListSpacingDecoration( class TypedListSpacingDecoration(
context: Context, context: Context,
private val addHorizontalPadding: Boolean,
) : ItemDecoration() { ) : ItemDecoration() {
private val spacingList = context.resources.getDimensionPixelOffset(R.dimen.list_spacing) private val spacingSmall = context.resources.getDimensionPixelOffset(R.dimen.list_spacing_small)
private val spacingGrid = context.resources.getDimensionPixelOffset(R.dimen.grid_spacing) private val spacingNormal = context.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal)
private val spacingGridTop = context.resources.getDimensionPixelOffset(R.dimen.grid_spacing_top) private val spacingLarge = context.resources.getDimensionPixelOffset(R.dimen.list_spacing_large)
override fun getItemOffsets( override fun getItemOffsets(
outRect: Rect, outRect: Rect,
@ -28,33 +29,45 @@ class TypedListSpacingDecoration(
ListItemType.FILTER_SORT, ListItemType.FILTER_SORT,
ListItemType.FILTER_TAG -> outRect.set(0) ListItemType.FILTER_TAG -> outRect.set(0)
ListItemType.HEADER -> outRect.set(spacingList, 0, spacingList, 0) ListItemType.HEADER,
ListItemType.FEED,
ListItemType.EXPLORE_SOURCE_LIST, ListItemType.EXPLORE_SOURCE_LIST,
ListItemType.MANGA_LIST -> outRect.set(spacingList, 0, spacingList, 0) ListItemType.MANGA_SCROBBLING,
ListItemType.MANGA_LIST -> outRect.set(0)
ListItemType.DOWNLOAD, ListItemType.DOWNLOAD,
ListItemType.MANGA_LIST_DETAILED -> outRect.set(spacingList) ListItemType.HINT_EMPTY,
ListItemType.MANGA_LIST_DETAILED -> outRect.set(spacingNormal)
ListItemType.PAGE_THUMB, ListItemType.PAGE_THUMB,
ListItemType.MANGA_GRID -> outRect.set(spacingGrid) ListItemType.MANGA_GRID -> outRect.set(spacingNormal)
ListItemType.EXPLORE_BUTTONS -> outRect.set(spacingNormal)
ListItemType.FOOTER_LOADING, ListItemType.FOOTER_LOADING,
ListItemType.FOOTER_ERROR, ListItemType.FOOTER_ERROR,
ListItemType.STATE_LOADING, ListItemType.STATE_LOADING,
ListItemType.STATE_ERROR, ListItemType.STATE_ERROR,
ListItemType.STATE_EMPTY, ListItemType.STATE_EMPTY,
ListItemType.EXPLORE_BUTTONS,
ListItemType.EXPLORE_SOURCE_GRID, ListItemType.EXPLORE_SOURCE_GRID,
ListItemType.EXPLORE_SUGGESTION, ListItemType.EXPLORE_SUGGESTION,
ListItemType.MANGA_NESTED_GROUP, ListItemType.MANGA_NESTED_GROUP,
ListItemType.CATEGORY_LARGE,
null -> outRect.set(0) null -> outRect.set(0)
ListItemType.TIP -> outRect.set(0) // TODO ListItemType.TIP -> outRect.set(0) // TODO
ListItemType.HINT_EMPTY, }
ListItemType.FEED -> outRect.set(spacingList, 0, spacingList, 0) if (addHorizontalPadding && !itemType.isEdgeToEdge()) {
outRect.set(
outRect.left + spacingNormal,
outRect.top,
outRect.right + spacingNormal,
outRect.bottom,
)
} }
} }
private fun Rect.set(spacing: Int) = set(spacing, spacing, spacing, spacing) private fun Rect.set(spacing: Int) = set(spacing, spacing, spacing, spacing)
private fun ListItemType?.isEdgeToEdge() = this == ListItemType.MANGA_NESTED_GROUP
} }

@ -23,7 +23,6 @@ import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.plus import org.koitharu.kotatsu.core.util.ext.plus
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.core.util.ext.showDistinct import org.koitharu.kotatsu.core.util.ext.showDistinct
import org.koitharu.kotatsu.core.util.ext.withArgs import org.koitharu.kotatsu.core.util.ext.withArgs
import org.koitharu.kotatsu.databinding.SheetPagesBinding import org.koitharu.kotatsu.databinding.SheetPagesBinding
@ -75,7 +74,7 @@ class PagesThumbnailsSheet :
clickListener = this@PagesThumbnailsSheet, clickListener = this@PagesThumbnailsSheet,
) )
with(binding.recyclerView) { with(binding.recyclerView) {
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, false))
adapter = thumbnailsAdapter adapter = thumbnailsAdapter
addOnLayoutChangeListener(spanResolver) addOnLayoutChangeListener(spanResolver)
spanResolver?.setGridSize(settings.gridSize / 100f, this) spanResolver?.setGridSize(settings.gridSize / 100f, this)

@ -38,9 +38,6 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
private val viewModel: ScrobblerConfigViewModel by viewModels() private val viewModel: ScrobblerConfigViewModel by viewModels()
private var paddingVertical = 0
private var paddingHorizontal = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityScrobblerConfigBinding.inflate(layoutInflater)) setContentView(ActivityScrobblerConfigBinding.inflate(layoutInflater))
@ -51,10 +48,7 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
adapter = listAdapter adapter = listAdapter
setHasFixedSize(true) setHasFixedSize(true)
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing) val decoration = TypedListSpacingDecoration(context, false)
paddingHorizontal = spacing
paddingVertical = resources.getDimensionPixelOffset(R.dimen.grid_spacing_outer)
val decoration = TypedListSpacingDecoration(context)
addItemDecoration(decoration) addItemDecoration(decoration)
} }
viewBinding.imageViewAvatar.setOnClickListener(this) viewBinding.imageViewAvatar.setOnClickListener(this)
@ -79,10 +73,11 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.recyclerView.updatePadding( val rv = viewBinding.recyclerView
left = insets.left + paddingHorizontal, rv.updatePadding(
right = insets.right + paddingHorizontal, left = insets.left + rv.paddingTop,
bottom = insets.bottom + paddingVertical, right = insets.right + rv.paddingTop,
bottom = insets.bottom + rv.paddingTop,
) )
} }

@ -1,16 +1,20 @@
package org.koitharu.kotatsu.scrobbling.common.ui.config.adapter package org.koitharu.kotatsu.scrobbling.common.ui.config.adapter
import android.widget.TextView import androidx.core.view.isInvisible
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.databinding.ItemHeaderButtonBinding
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
fun scrobblingHeaderAD() = adapterDelegate<ScrobblingStatus, ListModel>(R.layout.item_header) { fun scrobblingHeaderAD() = adapterDelegateViewBinding<ScrobblingStatus, ListModel, ItemHeaderButtonBinding>(
{ inflater, parent -> ItemHeaderButtonBinding.inflate(inflater, parent, false) },
) {
binding.buttonMore.isInvisible = true
val strings = context.resources.getStringArray(R.array.scrobbling_statuses)
bind { bind {
(itemView as TextView).text = context.resources binding.textViewTitle.text = strings.getOrNull(item.ordinal)
.getStringArray(R.array.scrobbling_statuses)
.getOrNull(item.ordinal)
} }
} }

@ -4,6 +4,7 @@ import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader import coil.ImageLoader
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
@ -15,8 +16,8 @@ class ScrobblingMangaAdapter(
) : BaseListAdapter<ListModel>() { ) : BaseListAdapter<ListModel>() {
init { init {
delegatesManager.addDelegate(scrobblingMangaAD(clickListener, coil, lifecycleOwner)) addDelegate(ListItemType.HEADER, scrobblingHeaderAD())
.addDelegate(scrobblingHeaderAD()) addDelegate(ListItemType.STATE_EMPTY, emptyStateListAD(coil, lifecycleOwner, null))
.addDelegate(emptyStateListAD(coil, lifecycleOwner, null)) addDelegate(ListItemType.MANGA_SCROBBLING, scrobblingMangaAD(clickListener, coil, lifecycleOwner))
} }
} }

@ -26,6 +26,7 @@ import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.withArgs import org.koitharu.kotatsu.core.util.ext.withArgs
import org.koitharu.kotatsu.databinding.SheetScrobblingSelectorBinding import org.koitharu.kotatsu.databinding.SheetScrobblingSelectorBinding
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
@ -63,6 +64,7 @@ class ScrobblingSelectorSheet :
with(binding.recyclerView) { with(binding.recyclerView) {
adapter = listAdapter adapter = listAdapter
addItemDecoration(decoration) addItemDecoration(decoration)
addItemDecoration(TypedListSpacingDecoration(context, false))
addOnScrollListener(PaginationScrollListener(4, this@ScrobblingSelectorSheet)) addOnScrollListener(PaginationScrollListener(4, this@ScrobblingSelectorSheet))
} }
binding.buttonDone.setOnClickListener(this) binding.buttonDone.setOnClickListener(this)

@ -4,6 +4,7 @@ import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader import coil.ImageLoader
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD
import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD
@ -18,9 +19,9 @@ class ScrobblerSelectorAdapter(
) : BaseListAdapter<ListModel>() { ) : BaseListAdapter<ListModel>() {
init { init {
delegatesManager.addDelegate(loadingStateAD()) addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
.addDelegate(scrobblingMangaAD(lifecycleOwner, coil, clickListener)) addDelegate(ListItemType.MANGA_SCROBBLING, scrobblingMangaAD(lifecycleOwner, coil, clickListener))
.addDelegate(loadingFooterAD()) addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
.addDelegate(scrobblerHintAD(stateHolderListener)) addDelegate(ListItemType.HINT_EMPTY, scrobblerHintAD(stateHolderListener))
} }
} }

@ -23,13 +23,13 @@ import org.koitharu.kotatsu.core.util.ShareHelper
import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.databinding.ActivitySearchMultiBinding import org.koitharu.kotatsu.databinding.ActivitySearchMultiBinding
import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.details.ui.DetailsActivity
import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver
import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet
import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener 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.ListHeader
import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
@ -83,6 +83,7 @@ class MultiSearchActivity :
) )
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.setHasFixedSize(true)
viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, true))
supportActionBar?.run { supportActionBar?.run {
setDisplayHomeAsUpEnabled(true) setDisplayHomeAsUpEnabled(true)
@ -100,7 +101,7 @@ class MultiSearchActivity :
right = insets.right, right = insets.right,
) )
viewBinding.recyclerView.updatePadding( viewBinding.recyclerView.updatePadding(
bottom = insets.bottom, bottom = insets.bottom + viewBinding.recyclerView.paddingTop,
) )
} }

@ -6,6 +6,7 @@ import coil.ImageLoader
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
import org.koitharu.kotatsu.list.ui.adapter.MangaListListener import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD
import org.koitharu.kotatsu.list.ui.adapter.errorStateListAD import org.koitharu.kotatsu.list.ui.adapter.errorStateListAD
@ -26,8 +27,8 @@ class MultiSearchAdapter(
init { init {
val pool = RecycledViewPool() val pool = RecycledViewPool()
delegatesManager addDelegate(
.addDelegate( ListItemType.MANGA_NESTED_GROUP,
searchResultsAD( searchResultsAD(
sharedPool = pool, sharedPool = pool,
lifecycleOwner = lifecycleOwner, lifecycleOwner = lifecycleOwner,
@ -38,9 +39,9 @@ class MultiSearchAdapter(
itemClickListener = itemClickListener, itemClickListener = itemClickListener,
), ),
) )
.addDelegate(loadingStateAD()) addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
.addDelegate(loadingFooterAD()) addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
.addDelegate(emptyStateListAD(coil, lifecycleOwner, listener)) addDelegate(ListItemType.STATE_EMPTY, emptyStateListAD(coil, lifecycleOwner, listener))
.addDelegate(errorStateListAD(listener)) addDelegate(ListItemType.STATE_ERROR, errorStateListAD(listener))
} }
} }

@ -58,7 +58,7 @@ class FeedFragment :
adapter = feedAdapter adapter = feedAdapter
setHasFixedSize(true) setHasFixedSize(true)
addOnScrollListener(PaginationScrollListener(4, this@FeedFragment)) addOnScrollListener(PaginationScrollListener(4, this@FeedFragment))
addItemDecoration(TypedListSpacingDecoration(context)) addItemDecoration(TypedListSpacingDecoration(context, true))
} }
binding.swipeRefreshLayout.setOnRefreshListener(this) binding.swipeRefreshLayout.setOnRefreshListener(this)
addMenuProvider( addMenuProvider(
@ -82,8 +82,9 @@ class FeedFragment :
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding( val rv = requireViewBinding().recyclerView
bottom = insets.bottom, rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
) )
} }

@ -5,32 +5,32 @@
<item> <item>
<selector> <selector>
<item <item
android:state_selected="true"
android:top="2dp"
android:right="2dp"
android:bottom="2dp" android:bottom="2dp"
android:left="2dp"> android:left="2dp"
android:right="2dp"
android:state_selected="true"
android:top="2dp">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<corners android:radius="@dimen/list_selector_corner" /> <corners android:radius="@dimen/list_selector_corner" />
<solid android:color="@color/selector_overlay" /> <solid android:color="@color/selector_overlay" />
</shape> </shape>
</item> </item>
<item <item
android:state_activated="true"
android:top="2dp"
android:right="2dp"
android:bottom="2dp" android:bottom="2dp"
android:left="2dp"> android:left="2dp"
android:right="2dp"
android:state_activated="true"
android:top="2dp">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<corners android:radius="@dimen/list_selector_corner" /> <corners android:radius="@dimen/list_selector_corner" />
<solid android:color="@color/selector_overlay" /> <solid android:color="@color/selector_overlay" />
</shape> </shape>
</item> </item>
<item <item
android:top="2dp"
android:right="2dp"
android:bottom="2dp" android:bottom="2dp"
android:left="2dp"> android:left="2dp"
android:right="2dp"
android:top="2dp">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<corners android:radius="@dimen/list_selector_corner" /> <corners android:radius="@dimen/list_selector_corner" />
<solid android:color="?android:attr/windowBackground" /> <solid android:color="?android:attr/windowBackground" />
@ -38,4 +38,15 @@
</item> </item>
</selector> </selector>
</item> </item>
<item
android:id="@android:id/mask"
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp">
<shape android:shape="rectangle">
<corners android:radius="@dimen/list_selector_corner" />
<solid android:color="@color/selector_overlay" />
</shape>
</item>
</ripple> </ripple>

@ -48,7 +48,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingVertical="@dimen/list_spacing" android:padding="@dimen/list_spacing_normal"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"

@ -35,7 +35,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="@dimen/list_spacing" android:padding="@dimen/list_spacing_normal"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"

@ -52,10 +52,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="@dimen/list_spacing" android:padding="@dimen/list_spacing_normal"
android:paddingTop="@dimen/grid_spacing_outer"
android:paddingRight="@dimen/list_spacing"
android:paddingBottom="@dimen/grid_spacing_outer"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
tools:navigationIcon="@drawable/abc_ic_clear_material"
tools:title="@string/settings">
<Button
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="@dimen/toolbar_button_margin"
android:text="@string/done" />
</com.google.android.material.appbar.MaterialToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="ifContentScrolls"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>

@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:padding="@dimen/list_spacing_normal"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/list_spacing"
android:scrollbars="vertical" android:scrollbars="vertical"
tools:listitem="@layout/item_explore_source_list" /> tools:listitem="@layout/item_explore_source_list" />

@ -17,6 +17,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingVertical="@dimen/list_spacing_normal"
app:bubbleSize="small" app:bubbleSize="small"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_feed" /> tools:listitem="@layout/item_feed" />

@ -17,8 +17,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingVertical="@dimen/list_spacing"
app:bubbleSize="small" app:bubbleSize="small"
android:padding="@dimen/list_spacing_normal"
tools:layoutManager="org.koitharu.kotatsu.core.ui.list.FitHeightLinearLayoutManager" tools:layoutManager="org.koitharu.kotatsu.core.ui.list.FitHeightLinearLayoutManager"
tools:listitem="@layout/item_manga_list" /> tools:listitem="@layout/item_manga_list" />

@ -13,7 +13,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="@dimen/list_spacing" android:padding="@dimen/list_spacing_normal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_feed" /> tools:listitem="@layout/item_feed" />

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.koitharu.kotatsu.core.ui.list.fastscroll.FastScrollRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
app:bubbleSize="small"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_feed" />
</FrameLayout>

@ -3,9 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:paddingHorizontal="@dimen/list_spacing"
android:paddingBottom="@dimen/list_spacing">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/button_local" android:id="@+id/button_local"

@ -67,9 +67,7 @@
android:id="@+id/scrollView_tags" android:id="@+id/scrollView_tags"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:scrollIndicators="start|end" android:scrollIndicators="start|end"
android:scrollbars="none" android:scrollbars="none"
@ -83,6 +81,7 @@
android:id="@+id/chips_tags" android:id="@+id/chips_tags"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="12dp"
app:chipSpacingHorizontal="6dp" app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp" app:chipSpacingVertical="6dp"
app:singleLine="true" /> app:singleLine="true" />

@ -52,7 +52,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:padding="@dimen/grid_spacing" android:padding="@dimen/list_spacing_normal"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_manga_list" /> tools:listitem="@layout/item_manga_list" />

@ -4,6 +4,10 @@
<!-- Common dimensions --> <!-- Common dimensions -->
<dimen name="margin_normal">16dp</dimen> <dimen name="margin_normal">16dp</dimen>
<dimen name="margin_small">8dp</dimen> <dimen name="margin_small">8dp</dimen>
<!-- List spacing -->
<dimen name="list_spacing_small">6dp</dimen>
<dimen name="list_spacing_normal">8dp</dimen>
<dimen name="list_spacing_large">12dp</dimen>
<!-- Navigation --> <!-- Navigation -->
<dimen name="nav_header_logo_size">36dp</dimen> <dimen name="nav_header_logo_size">36dp</dimen>

Loading…
Cancel
Save