Branch selection in chapters list
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
package org.koitharu.kotatsu.core.model
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
|
import org.koitharu.kotatsu.list.domain.ListFilterOption
|
||||||
|
|
||||||
|
fun ListFilterOption.toChipModel(isChecked: Boolean) = ChipsView.ChipModel(
|
||||||
|
title = titleText,
|
||||||
|
titleResId = titleResId,
|
||||||
|
icon = iconResId,
|
||||||
|
iconData = getIconData(),
|
||||||
|
isChecked = isChecked,
|
||||||
|
data = this,
|
||||||
|
)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.koitharu.kotatsu.core.util
|
||||||
|
|
||||||
|
import androidx.core.os.LocaleListCompat
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.iterator
|
||||||
|
|
||||||
|
class LocaleStringComparator : Comparator<String?> {
|
||||||
|
|
||||||
|
private val deviceLocales: List<String?>
|
||||||
|
|
||||||
|
init {
|
||||||
|
val localeList = LocaleListCompat.getAdjustedDefault()
|
||||||
|
deviceLocales = buildList(localeList.size() + 1) {
|
||||||
|
add(null)
|
||||||
|
val set = HashSet<String?>(localeList.size() + 1)
|
||||||
|
set.add(null)
|
||||||
|
for (locale in localeList) {
|
||||||
|
val lang = locale.getDisplayLanguage(locale).lowercase()
|
||||||
|
if (set.add(lang)) {
|
||||||
|
add(lang)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun compare(a: String?, b: String?): Int {
|
||||||
|
val indexA = deviceLocales.indexOf(a?.lowercase())
|
||||||
|
val indexB = deviceLocales.indexOf(b?.lowercase())
|
||||||
|
return when {
|
||||||
|
indexA < 0 && indexB < 0 -> compareValues(a, b)
|
||||||
|
indexA < 0 -> 1
|
||||||
|
indexB < 0 -> -1
|
||||||
|
else -> compareValues(indexA, indexB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.koitharu.kotatsu.details.domain
|
package org.koitharu.kotatsu.details.domain
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.core.util.LocaleStringComparator
|
||||||
import org.koitharu.kotatsu.details.ui.model.MangaBranch
|
import org.koitharu.kotatsu.details.ui.model.MangaBranch
|
||||||
|
|
||||||
class BranchComparator : Comparator<MangaBranch> {
|
class BranchComparator : Comparator<MangaBranch> {
|
||||||
|
|
||||||
override fun compare(o1: MangaBranch, o2: MangaBranch): Int = compareValues(o1.name, o2.name)
|
private val delegate = LocaleStringComparator()
|
||||||
|
|
||||||
|
override fun compare(o1: MangaBranch, o2: MangaBranch): Int = delegate.compare(o1.name, o2.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ fun MangaDetails.mapChapters(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<ChapterListItem>.withVolumeHeaders(context: Context): List<ListModel> {
|
fun List<ChapterListItem>.withVolumeHeaders(context: Context): MutableList<ListModel> {
|
||||||
var prevVolume = 0
|
var prevVolume = 0
|
||||||
val result = ArrayList<ListModel>((size * 1.4).toInt())
|
val result = ArrayList<ListModel>((size * 1.4).toInt())
|
||||||
for (item in this) {
|
for (item in this) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import coil3.size.Precision
|
|||||||
import coil3.size.Scale
|
import coil3.size.Scale
|
||||||
import coil3.transform.RoundedCornersTransformation
|
import coil3.transform.RoundedCornersTransformation
|
||||||
import coil3.util.CoilUtils
|
import coil3.util.CoilUtils
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
@@ -167,6 +168,7 @@ class DetailsActivity :
|
|||||||
TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView)
|
TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView)
|
||||||
viewBinding.containerBottomSheet?.let { sheet ->
|
viewBinding.containerBottomSheet?.let { sheet ->
|
||||||
onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(sheet))
|
onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(sheet))
|
||||||
|
BottomSheetBehavior.from(sheet).addBottomSheetCallback(DetailsBottomSheetCallback(viewBinding.swipeRefreshLayout))
|
||||||
}
|
}
|
||||||
TitleExpandListener(viewBinding.textViewTitle).attach()
|
TitleExpandListener(viewBinding.textViewTitle).attach()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.koitharu.kotatsu.details.ui
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
|
||||||
|
class DetailsBottomSheetCallback(
|
||||||
|
private val swipeRefreshLayout: SwipeRefreshLayout,
|
||||||
|
) : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
|
|
||||||
|
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||||
|
swipeRefreshLayout.isEnabled = newState == BottomSheetBehavior.STATE_COLLAPSED
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit
|
||||||
|
}
|
||||||
@@ -19,14 +19,17 @@ import kotlinx.coroutines.flow.update
|
|||||||
import kotlinx.coroutines.plus
|
import kotlinx.coroutines.plus
|
||||||
import okio.FileNotFoundException
|
import okio.FileNotFoundException
|
||||||
import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository
|
import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository
|
||||||
|
import org.koitharu.kotatsu.core.model.toChipModel
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
|
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
|
||||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||||
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
|
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
|
||||||
|
import org.koitharu.kotatsu.core.util.LocaleStringComparator
|
||||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.call
|
import org.koitharu.kotatsu.core.util.ext.call
|
||||||
import org.koitharu.kotatsu.core.util.ext.combine
|
import org.koitharu.kotatsu.core.util.ext.combine
|
||||||
import org.koitharu.kotatsu.core.util.ext.requireValue
|
import org.koitharu.kotatsu.core.util.ext.requireValue
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.sortedWithSafe
|
||||||
import org.koitharu.kotatsu.details.data.MangaDetails
|
import org.koitharu.kotatsu.details.data.MangaDetails
|
||||||
import org.koitharu.kotatsu.details.domain.DetailsInteractor
|
import org.koitharu.kotatsu.details.domain.DetailsInteractor
|
||||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||||
@@ -36,6 +39,7 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
|||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadTask
|
import org.koitharu.kotatsu.download.ui.worker.DownloadTask
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
|
import org.koitharu.kotatsu.list.domain.ListFilterOption
|
||||||
import org.koitharu.kotatsu.local.domain.DeleteLocalMangaUseCase
|
import org.koitharu.kotatsu.local.domain.DeleteLocalMangaUseCase
|
||||||
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
@@ -119,6 +123,18 @@ abstract class ChaptersPagesViewModel(
|
|||||||
(if (reversed) list.asReversed() else list).filterSearch(query)
|
(if (reversed) list.asReversed() else list).filterSearch(query)
|
||||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
||||||
|
|
||||||
|
val quickFilter = combine(
|
||||||
|
mangaDetails,
|
||||||
|
selectedBranch,
|
||||||
|
) { details, branch ->
|
||||||
|
val branches = details?.chapters?.keys?.sortedWithSafe(LocaleStringComparator()).orEmpty()
|
||||||
|
if (branches.size > 1) {
|
||||||
|
branches.map { ListFilterOption.Branch(it).toChipModel(it == branch) }
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
launchJob(Dispatchers.Default) {
|
launchJob(Dispatchers.Default) {
|
||||||
localStorageChanges
|
localStorageChanges
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.ancestors
|
import androidx.core.view.ancestors
|
||||||
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
@@ -22,6 +24,7 @@ import org.koitharu.kotatsu.core.ui.dialog.CommonAlertDialogs
|
|||||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper
|
import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper
|
||||||
|
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback
|
import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback
|
||||||
import org.koitharu.kotatsu.core.util.ext.dismissParentDialog
|
import org.koitharu.kotatsu.core.util.ext.dismissParentDialog
|
||||||
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
|
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
|
||||||
@@ -34,6 +37,7 @@ import org.koitharu.kotatsu.details.ui.adapter.ChaptersSelectionDecoration
|
|||||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||||
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesViewModel
|
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesViewModel
|
||||||
import org.koitharu.kotatsu.details.ui.withVolumeHeaders
|
import org.koitharu.kotatsu.details.ui.withVolumeHeaders
|
||||||
|
import org.koitharu.kotatsu.list.domain.ListFilterOption
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
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.reader.ui.ReaderActivity.IntentBuilder
|
import org.koitharu.kotatsu.reader.ui.ReaderActivity.IntentBuilder
|
||||||
@@ -45,7 +49,7 @@ import kotlin.math.roundToInt
|
|||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ChaptersFragment :
|
class ChaptersFragment :
|
||||||
BaseFragment<FragmentChaptersBinding>(),
|
BaseFragment<FragmentChaptersBinding>(),
|
||||||
OnListItemClickListener<ChapterListItem> {
|
OnListItemClickListener<ChapterListItem>, ChipsView.OnChipClickListener {
|
||||||
|
|
||||||
private val viewModel by ChaptersPagesViewModel.ActivityVMLazy(this)
|
private val viewModel by ChaptersPagesViewModel.ActivityVMLazy(this)
|
||||||
|
|
||||||
@@ -86,11 +90,13 @@ class ChaptersFragment :
|
|||||||
adapter = chaptersAdapter
|
adapter = chaptersAdapter
|
||||||
ChapterGridSpanHelper.attach(this)
|
ChapterGridSpanHelper.attach(this)
|
||||||
}
|
}
|
||||||
|
binding.chipsFilter.onChipClickListener = this
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged)
|
viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged)
|
||||||
viewModel.chapters
|
viewModel.chapters
|
||||||
.map { it.withVolumeHeaders(requireContext()) }
|
.map { it.withVolumeHeaders(requireContext()) }
|
||||||
.flowOn(Dispatchers.Default)
|
.flowOn(Dispatchers.Default)
|
||||||
.observe(viewLifecycleOwner, this::onChaptersChanged)
|
.observe(viewLifecycleOwner, this::onChaptersChanged)
|
||||||
|
viewModel.quickFilter.observe(viewLifecycleOwner, this::onFilterChanged)
|
||||||
viewModel.isChaptersEmpty.observe(viewLifecycleOwner) {
|
viewModel.isChaptersEmpty.observe(viewLifecycleOwner) {
|
||||||
binding.textViewHolder.isVisible = it
|
binding.textViewHolder.isVisible = it
|
||||||
}
|
}
|
||||||
@@ -128,6 +134,11 @@ class ChaptersFragment :
|
|||||||
return selectionController?.onItemContextClick(view, item.chapter.id) ?: false
|
return selectionController?.onItemContextClick(view, item.chapter.id) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onChipClick(chip: Chip, data: Any?) {
|
||||||
|
if (data !is ListFilterOption.Branch) return
|
||||||
|
viewModel.setSelectedBranch(data.titleText)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onWindowInsetsChanged(insets: Insets) = Unit
|
override fun onWindowInsetsChanged(insets: Insets) = Unit
|
||||||
|
|
||||||
private fun onChaptersChanged(list: List<ListModel>) {
|
private fun onChaptersChanged(list: List<ListModel>) {
|
||||||
@@ -148,6 +159,13 @@ class ChaptersFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onFilterChanged(list: List<ChipsView.ChipModel>) {
|
||||||
|
viewBinding?.chipsFilter?.run {
|
||||||
|
setChips(list)
|
||||||
|
isGone = list.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun onSelectChapter(chapterId: Long) {
|
private suspend fun onSelectChapter(chapterId: Long) {
|
||||||
if (!isResumed) {
|
if (!isResumed) {
|
||||||
view?.ancestors?.firstNotNullOfOrNull { it as? ViewPager2 }?.setCurrentItem(0, true)
|
view?.ancestors?.firstNotNullOfOrNull { it as? ViewPager2 }?.setCurrentItem(0, true)
|
||||||
|
|||||||
@@ -60,6 +60,20 @@ sealed interface ListFilterOption {
|
|||||||
get() = name
|
get() = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Branch(
|
||||||
|
override val titleText: String?,
|
||||||
|
) : ListFilterOption {
|
||||||
|
|
||||||
|
override val titleResId: Int
|
||||||
|
get() = if (titleText == null) R.string.system_default else 0
|
||||||
|
|
||||||
|
override val iconResId: Int
|
||||||
|
get() = R.drawable.ic_language
|
||||||
|
|
||||||
|
override val groupKey: String
|
||||||
|
get() = "_branch"
|
||||||
|
}
|
||||||
|
|
||||||
data class Tag(
|
data class Tag(
|
||||||
val tag: MangaTag
|
val tag: MangaTag
|
||||||
) : ListFilterOption {
|
) : ListFilterOption {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package org.koitharu.kotatsu.list.domain
|
|||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import org.koitharu.kotatsu.core.model.toChipModel
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.QuickFilter
|
import org.koitharu.kotatsu.list.ui.model.QuickFilter
|
||||||
import org.koitharu.kotatsu.parsers.util.suspendlazy.getOrNull
|
import org.koitharu.kotatsu.parsers.util.suspendlazy.getOrNull
|
||||||
import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy
|
import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy
|
||||||
@@ -52,14 +52,7 @@ abstract class MangaListQuickFilter(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
val availableOptions = availableFilterOptions.getOrNull()?.map { option ->
|
val availableOptions = availableFilterOptions.getOrNull()?.map { option ->
|
||||||
ChipsView.ChipModel(
|
option.toChipModel(isChecked = option in selectedOptions)
|
||||||
title = option.titleText,
|
|
||||||
titleResId = option.titleResId,
|
|
||||||
icon = option.iconResId,
|
|
||||||
iconData = option.getIconData(),
|
|
||||||
isChecked = option in selectedOptions,
|
|
||||||
data = option,
|
|
||||||
)
|
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
return if (availableOptions.isNotEmpty()) {
|
return if (availableOptions.isNotEmpty()) {
|
||||||
QuickFilter(availableOptions)
|
QuickFilter(availableOptions)
|
||||||
|
|||||||
@@ -1,15 +1,44 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<RelativeLayout
|
||||||
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"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/scrollView_filter"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingHorizontal="@dimen/list_spacing"
|
||||||
|
android:scrollbars="none">
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
|
android:id="@+id/chips_filter"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:paddingBottom="6dp"
|
||||||
|
app:chipStyle="@style/Widget.Kotatsu.Chip.Filter"
|
||||||
|
app:singleLine="true" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<org.koitharu.kotatsu.core.ui.list.fastscroll.FastScrollRecyclerView
|
<org.koitharu.kotatsu.core.ui.list.fastscroll.FastScrollRecyclerView
|
||||||
android:id="@+id/recyclerView_chapters"
|
android:id="@+id/recyclerView_chapters"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
|
android:layout_alignWithParentIfMissing="true"
|
||||||
|
android:layout_below="@id/scrollView_filter"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:scrollIndicators="top"
|
android:scrollIndicators="top"
|
||||||
@@ -21,7 +50,7 @@
|
|||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_centerInParent="true"
|
||||||
android:indeterminate="true"
|
android:indeterminate="true"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
@@ -30,7 +59,7 @@
|
|||||||
android:id="@+id/textView_holder"
|
android:id="@+id/textView_holder"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_centerInParent="true"
|
||||||
android:layout_marginStart="@dimen/margin_normal"
|
android:layout_marginStart="@dimen/margin_normal"
|
||||||
android:layout_marginTop="@dimen/margin_normal"
|
android:layout_marginTop="@dimen/margin_normal"
|
||||||
android:layout_marginEnd="@dimen/margin_normal"
|
android:layout_marginEnd="@dimen/margin_normal"
|
||||||
@@ -42,4 +71,4 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user