mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 02:21:51 +01:00
Using material fast scroll on manga details
This concludes the use of reddit's fastscroll Also updated the fast scroll's scroll listener so that the scroll handle respects its margins (thus making it reach the bottom of the manga details
This commit is contained in:
parent
60c3f24515
commit
4dae06803c
@ -206,7 +206,6 @@ dependencies {
|
|||||||
implementation("me.zhanghai.android.systemuihelper:library:1.0.0")
|
implementation("me.zhanghai.android.systemuihelper:library:1.0.0")
|
||||||
implementation("com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0")
|
implementation("com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0")
|
||||||
implementation("com.github.mthli:Slice:v1.2")
|
implementation("com.github.mthli:Slice:v1.2")
|
||||||
implementation("com.reddit:indicator-fast-scroll:1.2.1")
|
|
||||||
|
|
||||||
implementation("com.github.kizitonwose:AndroidTagGroup:1.6.0")
|
implementation("com.github.kizitonwose:AndroidTagGroup:1.6.0")
|
||||||
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
||||||
|
@ -3,9 +3,12 @@ package eu.kanade.tachiyomi.ui.library
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.davidea.fastscroller.FastScroller
|
import eu.davidea.fastscroller.FastScroller
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
||||||
|
import eu.kanade.tachiyomi.util.view.marginTop
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
FastScroller(context, attrs) {
|
FastScroller(context, attrs) {
|
||||||
@ -16,6 +19,7 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr
|
|||||||
)
|
)
|
||||||
autoHideEnabled = true
|
autoHideEnabled = true
|
||||||
ignoreTouchesOutsideHandle = true
|
ignoreTouchesOutsideHandle = true
|
||||||
|
updateScrollListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
@ -30,4 +34,22 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr
|
|||||||
bubble.translationX = (-45f).dpToPxEnd
|
bubble.translationX = (-45f).dpToPxEnd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateScrollListener() {
|
||||||
|
onScrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
if (!isEnabled || bubble == null || handle.isSelected) return
|
||||||
|
val verticalScrollOffset = recyclerView.computeVerticalScrollOffset()
|
||||||
|
val verticalScrollRange = recyclerView.computeVerticalScrollRange() - marginTop
|
||||||
|
val proportion =
|
||||||
|
verticalScrollOffset.toFloat() / (verticalScrollRange - height).toFloat()
|
||||||
|
setBubbleAndHandlePosition(height * proportion)
|
||||||
|
// If scroll amount is small, don't show it
|
||||||
|
if (minimumScrollThreshold == 0 || dy == 0 || abs(dy) > minimumScrollThreshold || scrollbarAnimator.isAnimating) {
|
||||||
|
showScrollbar()
|
||||||
|
if (autoHideEnabled) hideScrollbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,55 +59,34 @@ class MangaDetailsAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSectionText(position: Int): String? {
|
override fun onCreateBubbleText(position: Int): String {
|
||||||
val chapter = getItem(position) as? ChapterItem ?: return null
|
|
||||||
if (position == itemCount - 1) return "-"
|
|
||||||
return when (presenter.scrollType) {
|
|
||||||
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS ->
|
|
||||||
presenter.getGroupNumber(chapter)?.toString() ?: "*"
|
|
||||||
MangaDetailsPresenter.HUNDREDS_OF_CHAPTERS ->
|
|
||||||
if (chapter.chapter_number < 0) "*"
|
|
||||||
else (chapter.chapter_number / 100).toInt().toString()
|
|
||||||
MangaDetailsPresenter.TENS_OF_CHAPTERS ->
|
|
||||||
if (chapter.chapter_number < 0) "*"
|
|
||||||
else (chapter.chapter_number / 10).toInt().toString()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFullText(position: Int): String {
|
|
||||||
val chapter =
|
val chapter =
|
||||||
getItem(position) as? ChapterItem ?: return recyclerView.context.getString(R.string.top)
|
getItem(position) as? ChapterItem ?: return recyclerView.context.getString(R.string.top)
|
||||||
if (position == itemCount - 1) return recyclerView.context.getString(R.string.bottom)
|
|
||||||
return when (val scrollType = presenter.scrollType) {
|
return when (val scrollType = presenter.scrollType) {
|
||||||
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS -> {
|
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS -> {
|
||||||
val volume = presenter.getGroupNumber(chapter)
|
val volume = presenter.getGroupNumber(chapter)
|
||||||
if (volume != null) recyclerView.context.getString(
|
if (volume != null) {
|
||||||
|
recyclerView.context.getString(
|
||||||
if (scrollType == MangaDetailsPresenter.MULTIPLE_SEASONS) R.string.season_
|
if (scrollType == MangaDetailsPresenter.MULTIPLE_SEASONS) R.string.season_
|
||||||
else R.string.volume_, volume)
|
else R.string.volume_, volume
|
||||||
else recyclerView.context.getString(R.string.unknown)
|
)
|
||||||
|
} else {
|
||||||
|
recyclerView.context.getString(R.string.unknown)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MangaDetailsPresenter.HUNDREDS_OF_CHAPTERS -> recyclerView.context.getString(
|
|
||||||
R.string.chapters_, get100sRange(
|
|
||||||
chapter.chapter_number
|
|
||||||
)
|
|
||||||
)
|
|
||||||
MangaDetailsPresenter.TENS_OF_CHAPTERS -> recyclerView.context.getString(
|
MangaDetailsPresenter.TENS_OF_CHAPTERS -> recyclerView.context.getString(
|
||||||
R.string.chapters_, get10sRange(
|
R.string.chapters_, get10sRange(
|
||||||
chapter.chapter_number
|
chapter.chapter_number
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else -> recyclerView.context.getString(R.string.unknown)
|
else -> if (chapter.chapter_number > 0) {
|
||||||
|
recyclerView.context.getString(
|
||||||
|
R.string.chapter_, decimalFormat.format(chapter.chapter_number)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
chapter.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun get100sRange(value: Float): String {
|
|
||||||
val number = value.toInt()
|
|
||||||
return if (number < 100) "0-99"
|
|
||||||
else {
|
|
||||||
val hundred = number / 100
|
|
||||||
"${hundred}00-${hundred}99"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun get10sRange(value: Float): String {
|
private fun get10sRange(value: Float): String {
|
||||||
|
@ -53,8 +53,6 @@ import com.bumptech.glide.request.transition.Transition
|
|||||||
import com.bumptech.glide.signature.ObjectKey
|
import com.bumptech.glide.signature.ObjectKey
|
||||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.reddit.indicatorfastscroll.FastScrollItemIndicator
|
|
||||||
import com.reddit.indicatorfastscroll.FastScrollerView
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -101,14 +99,10 @@ import eu.kanade.tachiyomi.util.system.isOnline
|
|||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.getText
|
import eu.kanade.tachiyomi.util.view.getText
|
||||||
import eu.kanade.tachiyomi.util.view.hide
|
|
||||||
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
|
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
|
||||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||||
import eu.kanade.tachiyomi.util.view.setBackground
|
|
||||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||||
import eu.kanade.tachiyomi.util.view.setStartTranslationX
|
|
||||||
import eu.kanade.tachiyomi.util.view.setStyle
|
import eu.kanade.tachiyomi.util.view.setStyle
|
||||||
import eu.kanade.tachiyomi.util.view.show
|
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
@ -205,7 +199,7 @@ class MangaDetailsController : BaseController,
|
|||||||
|
|
||||||
setRecycler(view)
|
setRecycler(view)
|
||||||
setPaletteColor()
|
setPaletteColor()
|
||||||
setFastScroller()
|
adapter?.fastScroller = fast_scroller2
|
||||||
|
|
||||||
presenter.onCreate()
|
presenter.onCreate()
|
||||||
swipe_refresh.isRefreshing = presenter.isLoading
|
swipe_refresh.isRefreshing = presenter.isLoading
|
||||||
@ -259,17 +253,6 @@ class MangaDetailsController : BaseController,
|
|||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
val atTop = !recycler.canScrollVertically(-1)
|
val atTop = !recycler.canScrollVertically(-1)
|
||||||
if (atTop) getHeader()?.backdrop?.translationY = 0f
|
if (atTop) getHeader()?.backdrop?.translationY = 0f
|
||||||
when (newState) {
|
|
||||||
RecyclerView.SCROLL_STATE_DRAGGING -> {
|
|
||||||
scrollAnim?.cancel()
|
|
||||||
if (fast_scroller.translationX != 0f) {
|
|
||||||
showFastScroller()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RecyclerView.SCROLL_STATE_IDLE -> {
|
|
||||||
scrollAnim = fast_scroller.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -281,51 +264,12 @@ class MangaDetailsController : BaseController,
|
|||||||
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset)
|
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset)
|
||||||
// 1dp extra to line up chapter header and manga header
|
// 1dp extra to line up chapter header and manga header
|
||||||
getHeader()?.setTopHeight(headerHeight)
|
getHeader()?.setTopHeight(headerHeight)
|
||||||
fast_scroll_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
fast_scroller2.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
topMargin = headerHeight
|
topMargin = headerHeight
|
||||||
bottomMargin = insets.systemWindowInsetBottom
|
bottomMargin = insets.systemWindowInsetBottom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setFastScroller() {
|
|
||||||
fast_scroller.setStartTranslationX(true)
|
|
||||||
fast_scroller.setBackground(true)
|
|
||||||
fast_scroller.setupWithRecyclerView(recycler, { position ->
|
|
||||||
val letter = adapter?.getSectionText(position)
|
|
||||||
when {
|
|
||||||
presenter.scrollType == 0 -> null
|
|
||||||
letter != null -> FastScrollItemIndicator.Text(letter)
|
|
||||||
else -> FastScrollItemIndicator.Icon(R.drawable.ic_star_24dp)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
fast_scroller.useDefaultScroller = false
|
|
||||||
fast_scroller.itemIndicatorSelectedCallbacks += object :
|
|
||||||
FastScrollerView.ItemIndicatorSelectedCallback {
|
|
||||||
override fun onItemIndicatorSelected(
|
|
||||||
indicator: FastScrollItemIndicator,
|
|
||||||
indicatorCenterY: Int,
|
|
||||||
itemPosition: Int
|
|
||||||
) {
|
|
||||||
scrollAnim?.cancel()
|
|
||||||
scrollAnim = fast_scroller.hide(2000)
|
|
||||||
|
|
||||||
textAnim?.cancel()
|
|
||||||
textAnim = text_view_m.animate().alpha(0f).setDuration(250L).setStartDelay(1000)
|
|
||||||
textAnim?.start()
|
|
||||||
|
|
||||||
text_view_m.translationY = indicatorCenterY.toFloat() - text_view_m.height / 2
|
|
||||||
text_view_m.alpha = 1f
|
|
||||||
text_view_m.text = adapter?.getFullText(itemPosition)
|
|
||||||
val appbar = activity?.appbar
|
|
||||||
appbar?.y = 0f
|
|
||||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
|
||||||
itemPosition, headerHeight
|
|
||||||
)
|
|
||||||
colorToolbar(itemPosition > 0, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the toolbar to fully transparent or colored and translucent */
|
/** Set the toolbar to fully transparent or colored and translucent */
|
||||||
fun colorToolbar(isColor: Boolean, animate: Boolean = true) {
|
fun colorToolbar(isColor: Boolean, animate: Boolean = true) {
|
||||||
if (isColor == toolbarIsColored) return
|
if (isColor == toolbarIsColored) return
|
||||||
@ -594,12 +538,6 @@ class MangaDetailsController : BaseController,
|
|||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showFastScroller(animate: Boolean = true) {
|
|
||||||
if (presenter.scrollType != 0) {
|
|
||||||
fast_scroller.show(animate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addMangaHeader() {
|
private fun addMangaHeader() {
|
||||||
if (adapter?.scrollableHeaders?.isEmpty() == true) {
|
if (adapter?.scrollableHeaders?.isEmpty() == true) {
|
||||||
adapter?.removeAllScrollableHeaders()
|
adapter?.removeAllScrollableHeaders()
|
||||||
|
@ -251,7 +251,6 @@ class MangaDetailsPresenter(
|
|||||||
scrollType = when {
|
scrollType = when {
|
||||||
hasMultipleVolumes(chapters) -> MULTIPLE_VOLUMES
|
hasMultipleVolumes(chapters) -> MULTIPLE_VOLUMES
|
||||||
hasMultipleSeasons(chapters) -> MULTIPLE_SEASONS
|
hasMultipleSeasons(chapters) -> MULTIPLE_SEASONS
|
||||||
hasHundredsOfChapters(chapters) -> HUNDREDS_OF_CHAPTERS
|
|
||||||
hasTensOfChapters(chapters) -> TENS_OF_CHAPTERS
|
hasTensOfChapters(chapters) -> TENS_OF_CHAPTERS
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
@ -283,7 +282,7 @@ class MangaDetailsPresenter(
|
|||||||
val volNum = getVolumeNumber(it)
|
val volNum = getVolumeNumber(it)
|
||||||
if (volNum != null) {
|
if (volNum != null) {
|
||||||
volumeSet.add(volNum)
|
volumeSet.add(volNum)
|
||||||
if (volumeSet.size >= 3) return true
|
if (volumeSet.size >= 2) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -295,18 +294,14 @@ class MangaDetailsPresenter(
|
|||||||
val volNum = getSeasonNumber(it)
|
val volNum = getSeasonNumber(it)
|
||||||
if (volNum != null) {
|
if (volNum != null) {
|
||||||
volumeSet.add(volNum)
|
volumeSet.add(volNum)
|
||||||
if (volumeSet.size >= 3) return true
|
if (volumeSet.size >= 2) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasHundredsOfChapters(chapters: List<ChapterItem>): Boolean {
|
|
||||||
return chapters.size > 300
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasTensOfChapters(chapters: List<ChapterItem>): Boolean {
|
private fun hasTensOfChapters(chapters: List<ChapterItem>): Boolean {
|
||||||
return chapters.size in 21..300
|
return chapters.size > 20
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -878,7 +873,6 @@ class MangaDetailsPresenter(
|
|||||||
companion object {
|
companion object {
|
||||||
const val MULTIPLE_VOLUMES = 1
|
const val MULTIPLE_VOLUMES = 1
|
||||||
const val TENS_OF_CHAPTERS = 2
|
const val TENS_OF_CHAPTERS = 2
|
||||||
const val HUNDREDS_OF_CHAPTERS = 3
|
const val MULTIPLE_SEASONS = 3
|
||||||
const val MULTIPLE_SEASONS = 4
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.util.view
|
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.ViewPropertyAnimator
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.reddit.indicatorfastscroll.FastScrollerView
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
|
|
||||||
fun FastScrollerView.setBackground(hasBackground: Boolean) {
|
|
||||||
background = if (hasBackground) ContextCompat.getDrawable(
|
|
||||||
context, R.drawable.fast_scroll_background
|
|
||||||
) else null
|
|
||||||
textColor = ColorStateList.valueOf(
|
|
||||||
if (hasBackground) Color.WHITE
|
|
||||||
else context.getResourceColor(android.R.attr.textColorPrimary)
|
|
||||||
)
|
|
||||||
iconColor = textColor
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FastScrollerView.setStartTranslationX(shouldHide: Boolean) {
|
|
||||||
translationX = if (shouldHide) 25f.dpToPxEnd else 0f
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FastScrollerView.hide(duration: Long = 1000): ViewPropertyAnimator {
|
|
||||||
val scrollAnim = animate().setStartDelay(duration).setDuration(250)
|
|
||||||
.translationX(25f.dpToPxEnd)
|
|
||||||
scrollAnim.start()
|
|
||||||
return scrollAnim
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FastScrollerView.show(animate: Boolean = true) {
|
|
||||||
if (animate) animate().setStartDelay(0).setDuration(100).translationX(0f).start()
|
|
||||||
else translationX = 0f
|
|
||||||
}
|
|
@ -14,55 +14,25 @@
|
|||||||
android:background="?android:colorBackground">
|
android:background="?android:colorBackground">
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<FrameLayout
|
||||||
android:id="@+id/linear_recycler_layout"
|
android:id="@+id/linear_recycler_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler"
|
android:id="@+id/recycler"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="0.25"
|
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
tools:listitem="@layout/chapters_item" />
|
tools:listitem="@layout/chapters_item" />
|
||||||
</LinearLayout>
|
</FrameLayout>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<eu.kanade.tachiyomi.ui.library.MaterialFastScroll
|
||||||
android:id="@+id/fast_scroll_layout"
|
android:id="@+id/fast_scroller2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
app:fastScrollerBubbleEnabled="true" />
|
||||||
<com.reddit.indicatorfastscroll.FastScrollerView
|
|
||||||
android:id="@+id/fast_scroller"
|
|
||||||
android:layout_width="25dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:elevation="10dp"
|
|
||||||
android:paddingStart="1dp"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
app:iconColor="?android:attr/textColorPrimary"
|
|
||||||
app:layout_constrainedHeight="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/text_view_m"
|
|
||||||
style="@style/FloatingTextView"
|
|
||||||
android:layout_marginEnd="50dp"
|
|
||||||
android:alpha="0"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/fast_scroller"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/fast_scroller"
|
|
||||||
tools:text="Volume 12"
|
|
||||||
tools:alpha="1" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/full_backdrop"
|
android:id="@+id/full_backdrop"
|
||||||
|
Loading…
Reference in New Issue
Block a user