Reversed reader mode #15
parent
578c1c3825
commit
a885709ba9
@ -0,0 +1,36 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.reader.reversed
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
|
||||||
|
class ReversedPageAnimTransformer : ViewPager2.PageTransformer {
|
||||||
|
|
||||||
|
override fun transformPage(page: View, position: Float) {
|
||||||
|
with(page) {
|
||||||
|
val pageWidth = width
|
||||||
|
when {
|
||||||
|
position > 1 -> alpha = 0f
|
||||||
|
position >= 0 -> {
|
||||||
|
alpha = 1f
|
||||||
|
translationX = 0f
|
||||||
|
translationZ = 0f
|
||||||
|
scaleX = 1 + FACTOR * position
|
||||||
|
scaleY = 1f
|
||||||
|
}
|
||||||
|
position >= -1 -> {
|
||||||
|
alpha = 1f
|
||||||
|
translationX = pageWidth * -position
|
||||||
|
translationZ = -1f
|
||||||
|
scaleX = 1f
|
||||||
|
scaleY = 1f
|
||||||
|
}
|
||||||
|
else -> alpha = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
|
||||||
|
const val FACTOR = 0.1f
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.reader.reversed
|
||||||
|
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
|
import org.koitharu.kotatsu.ui.base.list.BaseViewHolder
|
||||||
|
import org.koitharu.kotatsu.ui.reader.PageLoader
|
||||||
|
import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter
|
||||||
|
import org.koitharu.kotatsu.ui.reader.base.GroupedList
|
||||||
|
import org.koitharu.kotatsu.ui.reader.standard.PageHolder
|
||||||
|
|
||||||
|
class ReversedPagesAdapter(
|
||||||
|
pages: GroupedList<Long, MangaPage>,
|
||||||
|
private val loader: PageLoader
|
||||||
|
) : BaseReaderAdapter(pages) {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup) = PageHolder(parent, loader)
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: BaseViewHolder<MangaPage, Unit>, position: Int) {
|
||||||
|
super.onBindViewHolder(holder, reversed(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(position: Int): MangaPage {
|
||||||
|
return super.getItem(reversed(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long {
|
||||||
|
return super.getItemId(reversed(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notifyItemsAppended(count: Int) {
|
||||||
|
super.notifyItemsPrepended(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notifyItemsPrepended(count: Int) {
|
||||||
|
super.notifyItemsAppended(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notifyItemsRemovedStart(count: Int) {
|
||||||
|
super.notifyItemsRemovedEnd(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notifyItemsRemovedEnd(count: Int) {
|
||||||
|
super.notifyItemsRemovedStart(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reversed(position: Int) = pages.size - position - 1
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.reader.reversed
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import kotlinx.android.synthetic.main.fragment_reader_standard.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.ui.reader.ReaderState
|
||||||
|
import org.koitharu.kotatsu.ui.reader.base.AbstractReader
|
||||||
|
import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter
|
||||||
|
import org.koitharu.kotatsu.ui.reader.base.GroupedList
|
||||||
|
import org.koitharu.kotatsu.ui.reader.standard.PageAnimTransformer
|
||||||
|
import org.koitharu.kotatsu.ui.reader.standard.PagerPaginationListener
|
||||||
|
import org.koitharu.kotatsu.utils.ext.doOnPageChanged
|
||||||
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
|
class ReversedReaderFragment : AbstractReader(R.layout.fragment_reader_standard),
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
private var paginationListener: PagerPaginationListener? = null
|
||||||
|
private val settings by inject<AppSettings>()
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
paginationListener = PagerPaginationListener(adapter!!, 2, this)
|
||||||
|
pager.adapter = adapter
|
||||||
|
if (settings.readerAnimation) {
|
||||||
|
pager.setPageTransformer(ReversedPageAnimTransformer())
|
||||||
|
}
|
||||||
|
pager.offscreenPageLimit = 2
|
||||||
|
pager.registerOnPageChangeCallback(paginationListener!!)
|
||||||
|
pager.doOnPageChanged {
|
||||||
|
notifyPageChanged(reversed(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAttach(context: Context) {
|
||||||
|
super.onAttach(context)
|
||||||
|
settings.subscribe(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetach() {
|
||||||
|
settings.unsubscribe(this)
|
||||||
|
super.onDetach()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
paginationListener = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter {
|
||||||
|
return ReversedPagesAdapter(dataSet, loader)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val itemsCount: Int
|
||||||
|
get() = adapter?.itemCount ?: 0
|
||||||
|
|
||||||
|
override fun getCurrentItem() = reversed(pager.currentItem)
|
||||||
|
|
||||||
|
override fun setCurrentItem(position: Int, isSmooth: Boolean) {
|
||||||
|
pager.setCurrentItem(reversed(position), isSmooth)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCurrentPageScroll() = 0
|
||||||
|
|
||||||
|
override fun restorePageScroll(position: Int, scroll: Int) = Unit
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
|
when (key) {
|
||||||
|
getString(R.string.key_reader_animation) -> {
|
||||||
|
if (settings.readerAnimation) {
|
||||||
|
pager.setPageTransformer(PageAnimTransformer())
|
||||||
|
} else {
|
||||||
|
pager.setPageTransformer(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reversed(position: Int) = (itemsCount - position - 1).coerceAtLeast(0)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun newInstance(state: ReaderState) = ReversedReaderFragment().withArgs(1) {
|
||||||
|
putParcelable(ARG_STATE, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000"
|
||||||
|
android:pathData="M4,21H19A2,2 0 0,0 21,19V13H17V15L13,12L17,9V11H21V5A2,2 0 0,0 19,3H4A2,2 0 0,0 2,5V19A2,2 0 0,0 4,21M4,15H8V17H4V15M4,11H11V13H4V11M4,7H11V9H4V7M21,11H24V13H21V11Z" />
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue