mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Make PagerPageHolder a subclass of ReaderPageImageView
This commit is contained in:
parent
df168e7154
commit
8dd2d2d0d4
2 changed files with 130 additions and 221 deletions
|
@ -10,6 +10,7 @@ import android.view.GestureDetector
|
|||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.WindowInsets
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.CallSuper
|
||||
|
@ -24,6 +25,7 @@ import com.davemorrissey.labs.subscaleview.ImageSource
|
|||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
|
||||
import com.github.chrisbanes.photoview.PhotoView
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonSubsamplingImageView
|
||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
||||
|
@ -46,7 +48,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||
private val isWebtoon: Boolean = false,
|
||||
) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes) {
|
||||
|
||||
private var pageView: View? = null
|
||||
protected var pageView: View? = null
|
||||
|
||||
private var config: Config? = null
|
||||
|
||||
|
@ -55,6 +57,8 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||
var onScaleChanged: ((newScale: Float) -> Unit)? = null
|
||||
var onViewClicked: (() -> Unit)? = null
|
||||
|
||||
open fun onNeedsLandscapeZoom() { }
|
||||
|
||||
@CallSuper
|
||||
open fun onImageLoaded() {
|
||||
onImageLoaded?.invoke()
|
||||
|
@ -133,16 +137,38 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||
addView(pageView, MATCH_PARENT, MATCH_PARENT)
|
||||
}
|
||||
|
||||
private fun SubsamplingScaleImageView.setupZoom(config: Config?) {
|
||||
protected fun SubsamplingScaleImageView.setupZoom(config: Config?) {
|
||||
// 5x zoom
|
||||
maxScale = scale * MAX_ZOOM_SCALE
|
||||
setDoubleTapZoomScale(scale * 2)
|
||||
|
||||
config ?: return
|
||||
|
||||
var centerV = 0f
|
||||
when (config.zoomStartPosition) {
|
||||
ZoomStartPosition.LEFT -> setScaleAndCenter(scale, PointF(0F, 0F))
|
||||
ZoomStartPosition.RIGHT -> setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0F))
|
||||
ZoomStartPosition.CENTER -> setScaleAndCenter(scale, center.also { it?.y = 0F })
|
||||
PagerConfig.ZoomType.Left -> {
|
||||
setScaleAndCenter(scale, PointF(0f, 0f))
|
||||
}
|
||||
PagerConfig.ZoomType.Right -> {
|
||||
setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f))
|
||||
centerV = sWidth.toFloat()
|
||||
}
|
||||
PagerConfig.ZoomType.Center -> {
|
||||
setScaleAndCenter(scale, center.also { it?.y = 0f })
|
||||
centerV = center?.x ?: 0f
|
||||
}
|
||||
}
|
||||
val insetInfo = config.insetInfo ?: return
|
||||
val topInsets = insetInfo.topCutoutInset
|
||||
val bottomInsets = insetInfo.bottomCutoutInset
|
||||
if (insetInfo.cutoutBehavior == PagerConfig.CUTOUT_START_EXTENDED &&
|
||||
topInsets + bottomInsets > 0 &&
|
||||
insetInfo.scaleTypeIsFullFit
|
||||
) {
|
||||
setScaleAndCenter(
|
||||
scale,
|
||||
PointF(centerV, (center?.y?.plus(topInsets)?.minus(bottomInsets) ?: 0f)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,11 +180,32 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||
setMinimumScaleType(config.minimumScaleType)
|
||||
setMinimumDpi(1) // Just so that very small image will be fit for initial load
|
||||
setCropBorders(config.cropBorders)
|
||||
if (config.insetInfo != null) {
|
||||
val topInsets = config.insetInfo.topCutoutInset
|
||||
val bottomInsets = config.insetInfo.bottomCutoutInset
|
||||
setExtendPastCutout(
|
||||
config.insetInfo.cutoutBehavior == PagerConfig.CUTOUT_START_EXTENDED &&
|
||||
config.insetInfo.scaleTypeIsFullFit && topInsets + bottomInsets > 0,
|
||||
)
|
||||
if ((config.insetInfo.cutoutBehavior != PagerConfig.CUTOUT_IGNORE || !config.insetInfo.scaleTypeIsFullFit) &&
|
||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q &&
|
||||
config.insetInfo.isFullscreen
|
||||
) {
|
||||
val insets: WindowInsets? = config.insetInfo.insets
|
||||
setExtraSpace(
|
||||
0f,
|
||||
insets?.displayCutout?.boundingRectTop?.height()?.toFloat() ?: 0f,
|
||||
0f,
|
||||
insets?.displayCutout?.boundingRectBottom?.height()?.toFloat() ?: 0f,
|
||||
)
|
||||
}
|
||||
}
|
||||
setOnImageEventListener(
|
||||
object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onReady() {
|
||||
// 5x zoom
|
||||
setupZoom(config)
|
||||
this@ReaderPageImageView.onNeedsLandscapeZoom()
|
||||
this@ReaderPageImageView.onImageLoaded()
|
||||
}
|
||||
|
||||
|
@ -262,13 +309,20 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||
val zoomDuration: Int,
|
||||
val minimumScaleType: Int = SCALE_TYPE_CENTER_INSIDE,
|
||||
val cropBorders: Boolean = false,
|
||||
val zoomStartPosition: ZoomStartPosition = ZoomStartPosition.CENTER,
|
||||
val zoomStartPosition: PagerConfig.ZoomType = PagerConfig.ZoomType.Center,
|
||||
val landscapeZoom: Boolean = false,
|
||||
val insetInfo: InsetInfo? = null,
|
||||
)
|
||||
|
||||
enum class ZoomStartPosition {
|
||||
LEFT, CENTER, RIGHT
|
||||
}
|
||||
data class InsetInfo(
|
||||
val cutoutBehavior: Int,
|
||||
val topCutoutInset: Float,
|
||||
val bottomCutoutInset: Float,
|
||||
val scaleTypeIsFullFit: Boolean,
|
||||
val isFullscreen: Boolean,
|
||||
val isSplitScreen: Boolean,
|
||||
val insets: WindowInsets?,
|
||||
)
|
||||
}
|
||||
|
||||
private const val MAX_ZOOM_SCALE = 5F
|
||||
|
|
|
@ -8,37 +8,24 @@ import android.graphics.BitmapFactory
|
|||
import android.graphics.Color
|
||||
import android.graphics.PointF
|
||||
import android.graphics.RectF
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.GestureDetector
|
||||
import android.os.Build
|
||||
import android.view.Gravity
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.view.WindowInsets
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import coil.imageLoader
|
||||
import coil.request.CachePolicy
|
||||
import coil.request.ImageRequest
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.github.chrisbanes.photoview.PhotoView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.Companion.CUTOUT_IGNORE
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.Companion.CUTOUT_START_EXTENDED
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType
|
||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.bottomCutoutInset
|
||||
|
@ -63,7 +50,6 @@ import rx.schedulers.Schedulers
|
|||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
@ -76,7 +62,7 @@ class PagerPageHolder(
|
|||
val viewer: PagerViewer,
|
||||
val page: ReaderPage,
|
||||
private var extraPage: ReaderPage? = null,
|
||||
) : FrameLayout(viewer.activity), ViewPagerAdapter.PositionableView {
|
||||
) : ReaderPageImageView(viewer.activity), ViewPagerAdapter.PositionableView {
|
||||
|
||||
/**
|
||||
* Item that identifies this view. Needed by the adapter to not recreate views.
|
||||
|
@ -89,16 +75,6 @@ class PagerPageHolder(
|
|||
*/
|
||||
private val progressBar = createProgressBar()
|
||||
|
||||
/**
|
||||
* Image view that supports subsampling on zoom.
|
||||
*/
|
||||
private var subsamplingImageView: SubsamplingScaleImageView? = null
|
||||
|
||||
/**
|
||||
* Simple image view only used on GIFs.
|
||||
*/
|
||||
private var imageView: ImageView? = null
|
||||
|
||||
/**
|
||||
* Retry button used to allow retrying.
|
||||
*/
|
||||
|
@ -160,6 +136,35 @@ class PagerPageHolder(
|
|||
)
|
||||
}
|
||||
|
||||
override fun onImageLoaded() {
|
||||
super.onImageLoaded()
|
||||
(pageView as? SubsamplingScaleImageView)?.apply {
|
||||
if (this@PagerPageHolder.extraPage == null &&
|
||||
this@PagerPageHolder.page.longPage == null &&
|
||||
sHeight < sWidth
|
||||
) {
|
||||
this@PagerPageHolder.page.longPage = true
|
||||
}
|
||||
}
|
||||
onImageDecoded()
|
||||
}
|
||||
|
||||
override fun onNeedsLandscapeZoom() {
|
||||
(pageView as? SubsamplingScaleImageView)?.apply {
|
||||
if (viewer.heldForwardZoom?.first == page.index) {
|
||||
landscapeZoom(viewer.heldForwardZoom?.second)
|
||||
viewer.heldForwardZoom = null
|
||||
} else if (isVisibleOnScreen()) {
|
||||
landscapeZoom(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onImageLoadError() {
|
||||
super.onImageLoadError()
|
||||
onImageDecodeError()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this view is detached from the window. Unsubscribes any active subscription.
|
||||
*/
|
||||
|
@ -173,30 +178,21 @@ class PagerPageHolder(
|
|||
unsubscribeReadImageHeader()
|
||||
scope?.cancel()
|
||||
scope = null
|
||||
subsamplingImageView?.setOnImageEventListener(null)
|
||||
(pageView as? SubsamplingScaleImageView)?.setOnImageEventListener(null)
|
||||
}
|
||||
|
||||
fun onPageSelected(forward: Boolean?) {
|
||||
subsamplingImageView?.apply {
|
||||
(pageView as? SubsamplingScaleImageView)?.apply {
|
||||
if (isReady) {
|
||||
landscapeZoom(forward)
|
||||
} else {
|
||||
forward ?: return@apply
|
||||
setOnImageEventListener(
|
||||
object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onImageLoaded() {
|
||||
if (this@PagerPageHolder.extraPage == null &&
|
||||
this@PagerPageHolder.page.longPage == null &&
|
||||
sHeight < sWidth
|
||||
) {
|
||||
this@PagerPageHolder.page.longPage = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReady() {
|
||||
setupZoom()
|
||||
setupZoom(imageConfig)
|
||||
landscapeZoom(forward)
|
||||
onImageDecoded()
|
||||
this@PagerPageHolder.onImageLoaded()
|
||||
}
|
||||
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
|
@ -223,7 +219,7 @@ class PagerPageHolder(
|
|||
* @param fn a function that returns the direction to check for
|
||||
*/
|
||||
private fun canPan(fn: (RectF) -> Float): Boolean {
|
||||
subsamplingImageView?.let { view ->
|
||||
(pageView as? SubsamplingScaleImageView)?.let { view ->
|
||||
RectF().let {
|
||||
view.getPanRemaining(it)
|
||||
return fn(it) > 0.01f
|
||||
|
@ -251,7 +247,7 @@ class PagerPageHolder(
|
|||
* @param fn a function that computes the new center of the image
|
||||
*/
|
||||
private fun pan(fn: (PointF, SubsamplingScaleImageView) -> PointF) {
|
||||
subsamplingImageView?.let { view ->
|
||||
(pageView as? SubsamplingScaleImageView)?.let { view ->
|
||||
val target = fn(view.center ?: return, view)
|
||||
view.animateCenter(target)!!
|
||||
.withEasing(SubsamplingScaleImageView.EASE_OUT_QUAD)
|
||||
|
@ -290,39 +286,6 @@ class PagerPageHolder(
|
|||
}
|
||||
}
|
||||
|
||||
private fun SubsamplingScaleImageView.setupZoom() {
|
||||
// 5x zoom
|
||||
maxScale = scale * MAX_ZOOM_SCALE
|
||||
setDoubleTapZoomScale(scale * 2)
|
||||
|
||||
var centerV = 0f
|
||||
val config = viewer.config
|
||||
when (config.imageZoomType) {
|
||||
ZoomType.Left -> {
|
||||
setScaleAndCenter(scale, PointF(0f, 0f))
|
||||
}
|
||||
ZoomType.Right -> {
|
||||
setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f))
|
||||
centerV = sWidth.toFloat()
|
||||
}
|
||||
ZoomType.Center -> {
|
||||
setScaleAndCenter(scale, center.also { it?.y = 0f })
|
||||
centerV = center?.x ?: 0f
|
||||
}
|
||||
}
|
||||
val topInsets = viewer.activity.window.decorView.rootWindowInsets.topCutoutInset().toFloat()
|
||||
val bottomInsets = viewer.activity.window.decorView.rootWindowInsets.bottomCutoutInset().toFloat()
|
||||
if (config.cutoutBehavior == CUTOUT_START_EXTENDED &&
|
||||
topInsets + bottomInsets > 0 &&
|
||||
config.scaleTypeIsFullFit()
|
||||
) {
|
||||
setScaleAndCenter(
|
||||
scale,
|
||||
PointF(centerV, (center?.y?.plus(topInsets)?.minus(bottomInsets) ?: 0f)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes the status of the page and notify the changes.
|
||||
*
|
||||
|
@ -521,28 +484,27 @@ class PagerPageHolder(
|
|||
.doOnNext { isAnimated ->
|
||||
if (!isAnimated) {
|
||||
if (viewer.config.readerTheme >= 2) {
|
||||
val imageView = initSubsamplingImageView()
|
||||
if (page.bg != null &&
|
||||
page.bgType == getBGType(viewer.config.readerTheme, context) + item.hashCode()
|
||||
) {
|
||||
imageView.setImage(ImageSource.inputStream(openStream!!))
|
||||
imageView.background = page.bg
|
||||
setImage(openStream!!, false, imageConfig)
|
||||
pageView?.background = page.bg
|
||||
}
|
||||
// if the user switches to automatic when pages are already cached, the bg needs to be loaded
|
||||
else {
|
||||
val bytesArray = openStream!!.readBytes()
|
||||
val bytesStream = bytesArray.inputStream()
|
||||
imageView.setImage(ImageSource.inputStream(bytesStream))
|
||||
setImage(bytesStream, false, imageConfig)
|
||||
bytesStream.close()
|
||||
|
||||
launchUI {
|
||||
scope?.launchUI {
|
||||
try {
|
||||
imageView.background = setBG(bytesArray)
|
||||
pageView?.background = setBG(bytesArray)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e.localizedMessage)
|
||||
imageView.background = ColorDrawable(Color.WHITE)
|
||||
pageView?.background = ColorDrawable(Color.WHITE)
|
||||
} finally {
|
||||
page.bg = imageView.background
|
||||
page.bg = pageView?.background
|
||||
page.bgType = getBGType(
|
||||
viewer.config.readerTheme,
|
||||
context,
|
||||
|
@ -551,14 +513,12 @@ class PagerPageHolder(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
val imageView = initSubsamplingImageView()
|
||||
imageView.setImage(ImageSource.inputStream(openStream!!))
|
||||
setImage(openStream!!, false, imageConfig)
|
||||
}
|
||||
} else {
|
||||
val imageView = initImageView()
|
||||
imageView.setAnimatedImage(openStream!!)
|
||||
setImage(openStream!!, true, imageConfig)
|
||||
if (viewer.config.readerTheme >= 2 && page.bg != null) {
|
||||
imageView.background = page.bg
|
||||
pageView?.background = page.bg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,6 +537,25 @@ class PagerPageHolder(
|
|||
.subscribe({}, {})
|
||||
}
|
||||
|
||||
private val imageConfig: Config
|
||||
get() = Config(
|
||||
zoomDuration = viewer.config.doubleTapAnimDuration,
|
||||
minimumScaleType = viewer.config.imageScaleType,
|
||||
cropBorders = viewer.config.imageCropBorders,
|
||||
zoomStartPosition = viewer.config.imageZoomType,
|
||||
landscapeZoom = viewer.config.landscapeZoom,
|
||||
insetInfo = InsetInfo(
|
||||
cutoutBehavior = viewer.config.cutoutBehavior,
|
||||
topCutoutInset = viewer.activity.window.decorView.rootWindowInsets.topCutoutInset().toFloat(),
|
||||
bottomCutoutInset = viewer.activity.window.decorView.rootWindowInsets.bottomCutoutInset().toFloat(),
|
||||
scaleTypeIsFullFit = viewer.config.scaleTypeIsFullFit(),
|
||||
isFullscreen = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
|
||||
viewer.config.isFullscreen && !viewer.activity.isInMultiWindowMode,
|
||||
isSplitScreen = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && viewer.activity.isInMultiWindowMode,
|
||||
insets = viewer.activity.window.decorView.rootWindowInsets,
|
||||
),
|
||||
)
|
||||
|
||||
private suspend fun setBG(bytesArray: ByteArray): Drawable {
|
||||
return withContext(Default) {
|
||||
val preferences by injectLazy<PreferencesHelper>()
|
||||
|
@ -635,99 +614,6 @@ class PagerPageHolder(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a subsampling scale view.
|
||||
*/
|
||||
private fun initSubsamplingImageView(): SubsamplingScaleImageView {
|
||||
if (subsamplingImageView != null) return subsamplingImageView!!
|
||||
|
||||
val config = viewer.config
|
||||
|
||||
subsamplingImageView = SubsamplingScaleImageView(context).apply {
|
||||
setMaxTileSize(GLUtil.maxTextureSize)
|
||||
setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
|
||||
setDoubleTapZoomDuration(config.doubleTapAnimDuration)
|
||||
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
|
||||
setMinimumScaleType(config.imageScaleType)
|
||||
setMinimumTileDpi(180)
|
||||
setMinimumDpi(1)
|
||||
setCropBorders(config.imageCropBorders)
|
||||
val topInsets = viewer.activity.window.decorView.rootWindowInsets.topCutoutInset().toFloat()
|
||||
val bottomInsets = viewer.activity.window.decorView.rootWindowInsets.bottomCutoutInset().toFloat()
|
||||
setExtendPastCutout(config.cutoutBehavior == CUTOUT_START_EXTENDED && config.scaleTypeIsFullFit() && topInsets + bottomInsets > 0)
|
||||
if ((config.cutoutBehavior != CUTOUT_IGNORE || !config.scaleTypeIsFullFit()) &&
|
||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q &&
|
||||
config.isFullscreen &&
|
||||
!viewer.activity.isInMultiWindowMode
|
||||
) {
|
||||
val insets: WindowInsets? = viewer.activity.window.decorView.rootWindowInsets
|
||||
setExtraSpace(
|
||||
0f,
|
||||
insets?.displayCutout?.boundingRectTop?.height()?.toFloat() ?: 0f,
|
||||
0f,
|
||||
insets?.displayCutout?.boundingRectBottom?.height()?.toFloat() ?: 0f,
|
||||
)
|
||||
}
|
||||
setOnImageEventListener(
|
||||
object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
|
||||
override fun onImageLoaded() {
|
||||
if (this@PagerPageHolder.extraPage == null &&
|
||||
this@PagerPageHolder.page.longPage == null &&
|
||||
sHeight < sWidth
|
||||
) {
|
||||
this@PagerPageHolder.page.longPage = true
|
||||
}
|
||||
}
|
||||
override fun onReady() {
|
||||
setupZoom()
|
||||
if (viewer.heldForwardZoom?.first == page.index) {
|
||||
landscapeZoom(viewer.heldForwardZoom?.second)
|
||||
viewer.heldForwardZoom = null
|
||||
} else if (isVisibleOnScreen()) {
|
||||
landscapeZoom(true)
|
||||
}
|
||||
onImageDecoded()
|
||||
}
|
||||
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
onImageDecodeError()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
addView(subsamplingImageView, MATCH_PARENT, MATCH_PARENT)
|
||||
return subsamplingImageView!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an image view, used for GIFs.
|
||||
*/
|
||||
private fun initImageView(): ImageView {
|
||||
if (imageView != null) return imageView!!
|
||||
|
||||
imageView = PhotoView(context, null).apply {
|
||||
adjustViewBounds = true
|
||||
setZoomTransitionDuration(viewer.config.doubleTapAnimDuration)
|
||||
setScaleLevels(1f, 2f, 3f)
|
||||
// Force 2 scale levels on double tap
|
||||
setOnDoubleTapListener(
|
||||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
if (scale > 1f) {
|
||||
setScale(1f, e.x, e.y, true)
|
||||
} else {
|
||||
setScale(2f, e.x, e.y, true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
addView(imageView, MATCH_PARENT, MATCH_PARENT)
|
||||
return imageView!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a button to retry pages.
|
||||
*/
|
||||
|
@ -951,35 +837,6 @@ class PagerPageHolder(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension method to set a [stream] into this ImageView.
|
||||
*/
|
||||
fun ImageView.setAnimatedImage(image: Any) {
|
||||
val data = when (image) {
|
||||
is Drawable -> image
|
||||
is InputStream -> ByteBuffer.wrap(image.readBytes())
|
||||
else -> throw IllegalArgumentException("Not implemented for class ${image::class.simpleName}")
|
||||
}
|
||||
val request = ImageRequest.Builder(context)
|
||||
.data(data)
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.diskCachePolicy(CachePolicy.DISABLED)
|
||||
.target(
|
||||
onSuccess = { result ->
|
||||
setImageDrawable(result)
|
||||
(result as? Animatable)?.start()
|
||||
isVisible = true
|
||||
this@PagerPageHolder.onImageDecoded()
|
||||
},
|
||||
onError = {
|
||||
this@PagerPageHolder.onImageDecodeError()
|
||||
},
|
||||
)
|
||||
.crossfade(false)
|
||||
.build()
|
||||
context.imageLoader.enqueue(request)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getBGType(readerTheme: Int, context: Context): Int {
|
||||
return if (readerTheme == 3) {
|
||||
|
@ -988,5 +845,3 @@ class PagerPageHolder(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val MAX_ZOOM_SCALE = 5F
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue