Update SubsamplingScaleImageView

pull/226/head
Koitharu 4 years ago
parent 9b0dc8b413
commit a68632a888
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -124,7 +124,7 @@ dependencies {
implementation 'io.coil-kt:coil-base:2.2.1' implementation 'io.coil-kt:coil-base:2.2.1'
implementation 'io.coil-kt:coil-svg:2.2.1' implementation 'io.coil-kt:coil-svg:2.2.1'
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:fc92ecb766' implementation 'com.github.KotatsuApp:subsampling-scale-image-view:cf1fcaa84e'
implementation 'com.github.solkin:disk-lru-cache:1.4' implementation 'com.github.solkin:disk-lru-cache:1.4'
implementation 'ch.acra:acra-http:5.9.6' implementation 'ch.acra:acra-http:5.9.6'

@ -16,6 +16,7 @@ import androidx.savedstate.SavedStateRegistryOwner
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import org.koitharu.kotatsu.base.ui.list.decor.AbstractSelectionItemDecoration import org.koitharu.kotatsu.base.ui.list.decor.AbstractSelectionItemDecoration
import org.koitharu.kotatsu.utils.ext.removeItemDecoration
private const val PROVIDER_NAME = "selection_decoration_sectioned" private const val PROVIDER_NAME = "selection_decoration_sectioned"
@ -60,12 +61,24 @@ class SectionedSelectionController<T : Any>(
startActionMode() startActionMode()
notifySelectionChanged() notifySelectionChanged()
} }
recyclerView.removeItemDecoration(decoration.javaClass)
recyclerView.addItemDecoration(decoration) recyclerView.addItemDecoration(decoration)
if (pendingData?.isEmpty() == true) { if (pendingData?.isEmpty() == true) {
pendingData = null pendingData = null
} }
} }
fun isAttached(recyclerView: RecyclerView): Boolean {
if (decorations.isEmpty()) return false
val anyDecoration = decorations.valueAt(0)
for (i in 0 until recyclerView.itemDecorationCount) {
if (recyclerView.getItemDecorationAt(i).javaClass == anyDecoration.javaClass) {
return true
}
}
return false
}
override fun saveState(): Bundle { override fun saveState(): Bundle {
val bundle = Bundle(decorations.size) val bundle = Bundle(decorations.size)
for ((k, v) in decorations) { for ((k, v) in decorations) {

@ -79,7 +79,7 @@ class ImageActivity : BaseActivity<ActivityImageBinding>() {
private fun setDrawable(drawable: Drawable?) { private fun setDrawable(drawable: Drawable?) {
if (drawable != null) { if (drawable != null) {
view.setImage(ImageSource.bitmap(drawable.toBitmap())) view.setImage(ImageSource.Bitmap(drawable.toBitmap()))
} else { } else {
view.recycle() view.recycle()
} }

@ -56,8 +56,7 @@ fun libraryGroupAD(
binding.buttonMore.setOnClickListener(listenerAdapter) binding.buttonMore.setOnClickListener(listenerAdapter)
bind { payloads -> bind { payloads ->
if (payloads.isEmpty()) { if (payloads.isEmpty() || !selectionController.isAttached(binding.recyclerView)) {
binding.recyclerView.removeItemDecoration(AbstractSelectionItemDecoration::class.java)
selectionController.attachToRecyclerView(item, binding.recyclerView) selectionController.attachToRecyclerView(item, binding.recyclerView)
} }
binding.textViewTitle.text = item.getTitle(context.resources) binding.textViewTitle.text = item.getTitle(context.resources)

@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.davemorrissey.labs.subscaleview.OnImageEventListener
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
@ -21,7 +22,7 @@ class PageHolderDelegate(
private val readerSettings: ReaderSettings, private val readerSettings: ReaderSettings,
private val callback: Callback, private val callback: Callback,
private val exceptionResolver: ExceptionResolver, private val exceptionResolver: ExceptionResolver,
) : SubsamplingScaleImageView.DefaultOnImageEventListener(), Observer<ReaderSettings> { ) : OnImageEventListener, Observer<ReaderSettings> {
private val scope = loader.loaderScope + Dispatchers.Main.immediate private val scope = loader.loaderScope + Dispatchers.Main.immediate
private var state = State.EMPTY private var state = State.EMPTY
@ -76,7 +77,7 @@ class PageHolderDelegate(
callback.onImageShown() callback.onImageShown()
} }
override fun onImageLoadError(e: Exception) { override fun onImageLoadError(e: Throwable) {
val file = this.file val file = this.file
error = e error = e
if (state == State.LOADED && e is IOException && file != null && file.exists()) { if (state == State.LOADED && e is IOException && file != null && file.exists()) {

@ -32,11 +32,11 @@ class ReversedPageHolder(
binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter()
when (settings.zoomMode) { when (settings.zoomMode) {
ZoomMode.FIT_CENTER -> { ZoomMode.FIT_CENTER -> {
setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
resetScaleAndCenter() resetScaleAndCenter()
} }
ZoomMode.FIT_HEIGHT -> { ZoomMode.FIT_HEIGHT -> {
setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
minScale = height / sHeight.toFloat() minScale = height / sHeight.toFloat()
setScaleAndCenter( setScaleAndCenter(
minScale, minScale,
@ -44,7 +44,7 @@ class ReversedPageHolder(
) )
} }
ZoomMode.FIT_WIDTH -> { ZoomMode.FIT_WIDTH -> {
setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
minScale = width / sWidth.toFloat() minScale = width / sWidth.toFloat()
setScaleAndCenter( setScaleAndCenter(
minScale, minScale,
@ -52,7 +52,7 @@ class ReversedPageHolder(
) )
} }
ZoomMode.KEEP_START -> { ZoomMode.KEEP_START -> {
setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
setScaleAndCenter( setScaleAndCenter(
maxScale, maxScale,
PointF(sWidth.toFloat(), 0f), PointF(sWidth.toFloat(), 0f),

@ -7,6 +7,7 @@ import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor import kotlinx.coroutines.asExecutor
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@ -28,8 +29,7 @@ open class PageHolder(
View.OnClickListener { View.OnClickListener {
init { init {
binding.ssiv.setExecutor(Dispatchers.Default.asExecutor()) binding.ssiv.isEagerLoadingEnabled = !isLowRamDevice(context)
binding.ssiv.setEagerLoadingEnabled(!isLowRamDevice(context))
binding.ssiv.setOnImageEventListener(delegate) binding.ssiv.setOnImageEventListener(delegate)
@Suppress("LeakingThis") @Suppress("LeakingThis")
bindingInfo.buttonRetry.setOnClickListener(this) bindingInfo.buttonRetry.setOnClickListener(this)
@ -63,7 +63,7 @@ open class PageHolder(
} }
override fun onImageReady(uri: Uri) { override fun onImageReady(uri: Uri) {
binding.ssiv.setImage(ImageSource.uri(uri)) binding.ssiv.setImage(ImageSource.Uri(uri))
} }
override fun onImageShowing(settings: ReaderSettings) { override fun onImageShowing(settings: ReaderSettings) {
@ -74,11 +74,11 @@ open class PageHolder(
binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter()
when (settings.zoomMode) { when (settings.zoomMode) {
ZoomMode.FIT_CENTER -> { ZoomMode.FIT_CENTER -> {
binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
binding.ssiv.resetScaleAndCenter() binding.ssiv.resetScaleAndCenter()
} }
ZoomMode.FIT_HEIGHT -> { ZoomMode.FIT_HEIGHT -> {
binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
binding.ssiv.minScale = binding.ssiv.height / binding.ssiv.sHeight.toFloat() binding.ssiv.minScale = binding.ssiv.height / binding.ssiv.sHeight.toFloat()
binding.ssiv.setScaleAndCenter( binding.ssiv.setScaleAndCenter(
binding.ssiv.minScale, binding.ssiv.minScale,
@ -86,7 +86,7 @@ open class PageHolder(
) )
} }
ZoomMode.FIT_WIDTH -> { ZoomMode.FIT_WIDTH -> {
binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
binding.ssiv.minScale = binding.ssiv.width / binding.ssiv.sWidth.toFloat() binding.ssiv.minScale = binding.ssiv.width / binding.ssiv.sWidth.toFloat()
binding.ssiv.setScaleAndCenter( binding.ssiv.setScaleAndCenter(
binding.ssiv.minScale, binding.ssiv.minScale,
@ -94,7 +94,7 @@ open class PageHolder(
) )
} }
ZoomMode.KEEP_START -> { ZoomMode.KEEP_START -> {
binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
binding.ssiv.setScaleAndCenter( binding.ssiv.setScaleAndCenter(
binding.ssiv.maxScale, binding.ssiv.maxScale,
PointF(0f, 0f), PointF(0f, 0f),

@ -5,6 +5,7 @@ import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding
@ -26,6 +27,7 @@ class WebtoonHolder(
private var scrollToRestore = 0 private var scrollToRestore = 0
init { init {
binding.ssiv.regionDecoderFactory = SkiaPooledImageRegionDecoder.Factory()
binding.ssiv.setOnImageEventListener(delegate) binding.ssiv.setOnImageEventListener(delegate)
bindingInfo.buttonRetry.setOnClickListener(this) bindingInfo.buttonRetry.setOnClickListener(this)
GoneOnInvisibleListener(bindingInfo.progressBar).attach() GoneOnInvisibleListener(bindingInfo.progressBar).attach()
@ -56,13 +58,13 @@ class WebtoonHolder(
} }
override fun onImageReady(uri: Uri) { override fun onImageReady(uri: Uri) {
binding.ssiv.setImage(ImageSource.uri(uri)) binding.ssiv.setImage(ImageSource.Uri(uri))
} }
override fun onImageShowing(settings: ReaderSettings) { override fun onImageShowing(settings: ReaderSettings) {
binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter()
with(binding.ssiv) { with(binding.ssiv) {
setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
minScale = width / sWidth.toFloat() minScale = width / sWidth.toFloat()
maxScale = minScale maxScale = minScale
scrollTo( scrollTo(

@ -5,10 +5,7 @@ import android.graphics.PointF
import android.util.AttributeSet import android.util.AttributeSet
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import org.koitharu.kotatsu.parsers.util.toIntUp import org.koitharu.kotatsu.parsers.util.toIntUp
import org.koitharu.kotatsu.utils.ext.isLowRamDevice
import org.koitharu.kotatsu.utils.ext.parents import org.koitharu.kotatsu.utils.ext.parents
private const val SCROLL_UNKNOWN = -1 private const val SCROLL_UNKNOWN = -1
@ -23,11 +20,6 @@ class WebtoonImageView @JvmOverloads constructor(
private var scrollPos = 0 private var scrollPos = 0
private var scrollRange = SCROLL_UNKNOWN private var scrollRange = SCROLL_UNKNOWN
init {
setExecutor(Dispatchers.Default.asExecutor())
setEagerLoadingEnabled(!isLowRamDevice(context))
}
fun scrollBy(delta: Int) { fun scrollBy(delta: Int) {
val maxScroll = getScrollRange() val maxScroll = getScrollRange()
if (maxScroll == 0) { if (maxScroll == 0) {

Loading…
Cancel
Save