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