From c0a0d60c879203cb9dea010b551c3c7df6dc1697 Mon Sep 17 00:00:00 2001 From: len Date: Sat, 30 Jul 2016 15:51:49 +0200 Subject: [PATCH] Replace page fragments with views --- .../{PagerReaderFragment.kt => PageView.kt} | 170 +++++++----------- .../ui/reader/viewer/pager/PagerReader.kt | 13 +- .../reader/viewer/pager/PagerReaderAdapter.kt | 61 ++----- .../tachiyomi/widget/ViewPagerAdapter.kt | 30 ++++ app/src/main/res/layout/item_pager_reader.xml | 4 +- 5 files changed, 116 insertions(+), 162 deletions(-) rename app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/{PagerReaderFragment.kt => PageView.kt} (53%) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt similarity index 53% rename from app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.kt rename to app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt index 0c172a086..523fbba68 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt @@ -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()) - 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()) + 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 - -} +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt index f1c0e32a5..fafd4f3a7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt @@ -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)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderAdapter.kt index 9c2990b51..fe3fadfc0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderAdapter.kt @@ -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) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt new file mode 100644 index 000000000..c2c21a66b --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/ViewPagerAdapter.kt @@ -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 + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/item_pager_reader.xml b/app/src/main/res/layout/item_pager_reader.xml index 4fefdc9b1..3b5f3d8c9 100644 --- a/app/src/main/res/layout/item_pager_reader.xml +++ b/app/src/main/res/layout/item_pager_reader.xml @@ -1,6 +1,6 @@ - @@ -40,4 +40,4 @@ android:layout_gravity="center" android:visibility="gone"/> - \ No newline at end of file + \ No newline at end of file