Replace page fragments with views
Cette révision appartient à :
Parent
9cf5a4cac0
révision
c0a0d60c87
5 fichiers modifiés avec 116 ajouts et 162 suppressions
|
@ -1,23 +1,23 @@
|
|||
package eu.kanade.tachiyomi.ui.reader.viewer.pager
|
||||
|
||||
import android.graphics.PointF
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.LayoutInflater
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.PageDecodeErrorLayout
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_CENTER
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_LEFT
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_RIGHT
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.RightToLeftReader
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalReader
|
||||
import kotlinx.android.synthetic.main.chapter_image.*
|
||||
import kotlinx.android.synthetic.main.item_pager_reader.*
|
||||
import kotlinx.android.synthetic.main.chapter_image.view.*
|
||||
import kotlinx.android.synthetic.main.item_pager_reader.view.*
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
@ -25,41 +25,15 @@ import rx.subjects.PublishSubject
|
|||
import rx.subjects.SerializedSubject
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
* Fragment for a single page of the ViewPager reader.
|
||||
* All the elements from the layout file "item_pager_reader" are available in this class.
|
||||
*/
|
||||
class PagerReaderFragment : BaseFragment() {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates a new instance of this fragment.
|
||||
*
|
||||
* @return a new instance of [PagerReaderFragment].
|
||||
*/
|
||||
fun newInstance(): PagerReaderFragment {
|
||||
return PagerReaderFragment()
|
||||
}
|
||||
}
|
||||
class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
|
||||
: FrameLayout(context, attrs) {
|
||||
|
||||
/**
|
||||
* Page of a chapter.
|
||||
*/
|
||||
var page: Page? = null
|
||||
set(value) {
|
||||
field = value
|
||||
// Observe status if the view is initialized
|
||||
if (view != null) {
|
||||
observeStatus()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Position of the fragment in the adapter.
|
||||
*/
|
||||
var position = -1
|
||||
private set
|
||||
|
||||
/**
|
||||
* Subscription for progress changes of the page.
|
||||
|
@ -71,47 +45,34 @@ class PagerReaderFragment : BaseFragment() {
|
|||
*/
|
||||
private var statusSubscription: Subscription? = null
|
||||
|
||||
/**
|
||||
* Text color for black theme.
|
||||
*/
|
||||
private val whiteColor by lazy { ContextCompat.getColor(context, R.color.textColorSecondaryDark) }
|
||||
fun initialize(reader: PagerReader, page: Page?) {
|
||||
val activity = reader.activity as ReaderActivity
|
||||
|
||||
/**
|
||||
* Text color for white theme.
|
||||
*/
|
||||
private val blackColor by lazy { ContextCompat.getColor(context, R.color.textColorSecondaryLight) }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.item_pager_reader, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedState: Bundle?) {
|
||||
if (readerActivity.readerTheme == ReaderActivity.BLACK_THEME) {
|
||||
progress_text.setTextColor(whiteColor)
|
||||
} else {
|
||||
progress_text.setTextColor(blackColor)
|
||||
when (activity.readerTheme) {
|
||||
ReaderActivity.BLACK_THEME -> progress_text.setTextColor(reader.whiteColor)
|
||||
ReaderActivity.WHITE_THEME -> progress_text.setTextColor(reader.blackColor)
|
||||
}
|
||||
|
||||
if (pagerReader is RightToLeftReader) {
|
||||
view.rotation = -180f
|
||||
if (reader is RightToLeftReader) {
|
||||
rotation = -180f
|
||||
}
|
||||
|
||||
with(image_view) {
|
||||
setMaxBitmapDimensions(readerActivity.maxBitmapSize)
|
||||
setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED)
|
||||
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
|
||||
setMinimumScaleType(pagerReader.scaleType)
|
||||
setMaxBitmapDimensions((reader.activity as ReaderActivity).maxBitmapSize)
|
||||
setDoubleTapZoomStyle(com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.ZOOM_FOCUS_FIXED)
|
||||
setPanLimit(com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
|
||||
setMinimumScaleType(reader.scaleType)
|
||||
setMinimumDpi(50)
|
||||
setRegionDecoderClass(pagerReader.regionDecoderClass)
|
||||
setBitmapDecoderClass(pagerReader.bitmapDecoderClass)
|
||||
setVerticalScrollingParent(pagerReader is VerticalReader)
|
||||
setOnTouchListener { v, motionEvent -> pagerReader.gestureDetector.onTouchEvent(motionEvent) }
|
||||
setRegionDecoderClass(reader.regionDecoderClass)
|
||||
setBitmapDecoderClass(reader.bitmapDecoderClass)
|
||||
setVerticalScrollingParent(reader is VerticalReader)
|
||||
setOnTouchListener { v, motionEvent -> reader.gestureDetector.onTouchEvent(motionEvent) }
|
||||
setOnImageEventListener(object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onReady() {
|
||||
when (pagerReader.zoomType) {
|
||||
PagerReader.ALIGN_LEFT -> setScaleAndCenter(scale, PointF(0f, 0f))
|
||||
PagerReader.ALIGN_RIGHT -> setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f))
|
||||
PagerReader.ALIGN_CENTER -> {
|
||||
when (reader.zoomType) {
|
||||
ALIGN_LEFT -> setScaleAndCenter(scale, android.graphics.PointF(0f, 0f))
|
||||
ALIGN_RIGHT -> setScaleAndCenter(scale, android.graphics.PointF(sWidth.toFloat(), 0f))
|
||||
ALIGN_CENTER -> {
|
||||
val newCenter = center
|
||||
newCenter.y = 0f
|
||||
setScaleAndCenter(scale, newCenter)
|
||||
|
@ -120,27 +81,34 @@ class PagerReaderFragment : BaseFragment() {
|
|||
}
|
||||
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
onImageDecodeError()
|
||||
onImageDecodeError(activity)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
retry_button.setOnTouchListener { v, event ->
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
readerActivity.presenter.retryPage(page)
|
||||
activity.presenter.retryPage(page)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
observeStatus()
|
||||
if (page != null) {
|
||||
this.page = page
|
||||
observeStatus()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
fun cleanup() {
|
||||
unsubscribeProgress()
|
||||
unsubscribeStatus()
|
||||
image_view.setOnTouchListener(null)
|
||||
image_view.setOnImageEventListener(null)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
cleanup()
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,33 +117,31 @@ class PagerReaderFragment : BaseFragment() {
|
|||
* @see processStatus
|
||||
*/
|
||||
private fun observeStatus() {
|
||||
page?.let { page ->
|
||||
val statusSubject = SerializedSubject(PublishSubject.create<Int>())
|
||||
page.setStatusSubject(statusSubject)
|
||||
statusSubscription?.unsubscribe()
|
||||
val page = page ?: return
|
||||
|
||||
statusSubscription?.unsubscribe()
|
||||
statusSubscription = statusSubject.startWith(page.status)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { processStatus(it) }
|
||||
}
|
||||
val statusSubject = SerializedSubject(PublishSubject.create<Int>())
|
||||
page.setStatusSubject(statusSubject)
|
||||
|
||||
statusSubscription = statusSubject.startWith(page.status)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { processStatus(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes the progress of the page and updates view.
|
||||
*/
|
||||
private fun observeProgress() {
|
||||
val currentValue = AtomicInteger(-1)
|
||||
|
||||
progressSubscription?.unsubscribe()
|
||||
val page = page ?: return
|
||||
|
||||
progressSubscription = Observable.interval(100, TimeUnit.MILLISECONDS)
|
||||
.map { page.progress }
|
||||
.distinctUntilChanged()
|
||||
.onBackpressureLatest()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
// Refresh UI only if progress change
|
||||
if (page?.progress != currentValue.get()) {
|
||||
currentValue.set(page?.progress ?: 0)
|
||||
progress_text.text = getString(R.string.download_progress, currentValue.get())
|
||||
}
|
||||
.subscribe { progress ->
|
||||
progress_text.text = context.getString(R.string.download_progress, progress)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,27 +235,13 @@ class PagerReaderFragment : BaseFragment() {
|
|||
/**
|
||||
* Called when an image fails to decode.
|
||||
*/
|
||||
private fun onImageDecodeError() {
|
||||
val view = view as? ViewGroup ?: return
|
||||
|
||||
private fun onImageDecodeError(activity: ReaderActivity) {
|
||||
page?.let { page ->
|
||||
val errorLayout = PageDecodeErrorLayout(context, page, readerActivity.readerTheme,
|
||||
{ readerActivity.presenter.retryPage(page) })
|
||||
val errorLayout = PageDecodeErrorLayout(context, page, activity.readerTheme,
|
||||
{ activity.presenter.retryPage(page) })
|
||||
|
||||
view.addView(errorLayout)
|
||||
addView(errorLayout)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Property to get the reader activity.
|
||||
*/
|
||||
private val readerActivity: ReaderActivity
|
||||
get() = activity as ReaderActivity
|
||||
|
||||
/**
|
||||
* Property to get the pager reader.
|
||||
*/
|
||||
private val pagerReader: PagerReader
|
||||
get() = parentFragment as PagerReader
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.reader.viewer.pager
|
||||
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
|
@ -90,13 +91,23 @@ abstract class PagerReader : BaseReader() {
|
|||
var zoomType = 1
|
||||
private set
|
||||
|
||||
/**
|
||||
* Text color for black theme.
|
||||
*/
|
||||
val whiteColor by lazy { ContextCompat.getColor(context, R.color.textColorSecondaryDark) }
|
||||
|
||||
/**
|
||||
* Text color for white theme.
|
||||
*/
|
||||
val blackColor by lazy { ContextCompat.getColor(context, R.color.textColorSecondaryLight) }
|
||||
|
||||
/**
|
||||
* Initializes the pager.
|
||||
*
|
||||
* @param pager the pager to initialize.
|
||||
*/
|
||||
protected fun initializePager(pager: Pager) {
|
||||
adapter = PagerReaderAdapter(childFragmentManager)
|
||||
adapter = PagerReaderAdapter(this)
|
||||
|
||||
this.pager = pager.apply {
|
||||
setLayoutParams(ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT))
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
package eu.kanade.tachiyomi.ui.reader.viewer.pager
|
||||
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v4.app.FragmentStatePagerAdapter
|
||||
import android.support.v4.view.PagerAdapter
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.util.inflate
|
||||
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
|
||||
|
||||
/**
|
||||
* Adapter of pages for a ViewPager.
|
||||
*
|
||||
* @param fm the fragment manager.
|
||||
*/
|
||||
class PagerReaderAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
||||
class PagerReaderAdapter(private val reader: PagerReader) : ViewPagerAdapter() {
|
||||
|
||||
/**
|
||||
* Pages stored in the adapter.
|
||||
|
@ -24,6 +21,12 @@ class PagerReaderAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun createView(container: ViewGroup, position: Int): View {
|
||||
val view = container.inflate(R.layout.item_pager_reader) as PageView
|
||||
view.initialize(reader, pages?.getOrNull(position))
|
||||
return view
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of pages.
|
||||
*
|
||||
|
@ -33,46 +36,4 @@ class PagerReaderAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
|||
return pages?.size ?: 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new fragment for the given position when it's called.
|
||||
*
|
||||
* @param position the position to instantiate.
|
||||
* @return a fragment for the given position.
|
||||
*/
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return PagerReaderFragment.newInstance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a fragment in the given position.
|
||||
*
|
||||
* @param container the parent view.
|
||||
* @param position the position to instantiate.
|
||||
* @return an instance of a fragment for the given position.
|
||||
*/
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val f = super.instantiateItem(container, position) as PagerReaderFragment
|
||||
f.page = pages!![position]
|
||||
f.position = position
|
||||
return f
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of a given item.
|
||||
*
|
||||
* @param obj the item to find its position.
|
||||
* @return the position for the item.
|
||||
*/
|
||||
override fun getItemPosition(obj: Any): Int {
|
||||
val f = obj as PagerReaderFragment
|
||||
val position = f.position
|
||||
if (position >= 0 && position < count) {
|
||||
if (pages!![position] === f.page) {
|
||||
return PagerAdapter.POSITION_UNCHANGED
|
||||
} else {
|
||||
return PagerAdapter.POSITION_NONE
|
||||
}
|
||||
}
|
||||
return super.getItemPosition(obj)
|
||||
}
|
||||
}
|
||||
|
|
30
app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt
Fichier normal
30
app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt
Fichier normal
|
@ -0,0 +1,30 @@
|
|||
package eu.kanade.tachiyomi.widget
|
||||
|
||||
import android.support.v4.view.PagerAdapter
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
abstract class ViewPagerAdapter : PagerAdapter() {
|
||||
|
||||
protected abstract fun createView(container: ViewGroup, position: Int): View
|
||||
|
||||
protected open fun destroyView(container: ViewGroup, position: Int, view: View) {
|
||||
}
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val view = createView(container, position)
|
||||
container.addView(view)
|
||||
return view
|
||||
}
|
||||
|
||||
override fun destroyItem(container: ViewGroup, position: Int, obj: Any) {
|
||||
val view = obj as View
|
||||
destroyView(container, position, view)
|
||||
container.removeView(view)
|
||||
}
|
||||
|
||||
override fun isViewFromObject(view: View, obj: Any): Boolean {
|
||||
return view === obj
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout
|
||||
<eu.kanade.tachiyomi.ui.reader.viewer.pager.PageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
@ -40,4 +40,4 @@
|
|||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</FrameLayout>
|
||||
</eu.kanade.tachiyomi.ui.reader.viewer.pager.PageView>
|
Référencer dans un nouveau ticket