From 8398c01929d7546830511c357f4c6e0d7f1c9e8c Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 18 Sep 2023 12:12:18 +0300 Subject: [PATCH] Improve keyboard control in reader --- app/build.gradle | 2 +- .../kotatsu/reader/ui/ReaderActivity.kt | 6 +- .../reader/ui/ReaderControlDelegate.kt | 26 +++++-- .../koitharu/kotatsu/reader/ui/ScrollTimer.kt | 2 +- .../reader/ui/pager/BaseReaderFragment.kt | 2 +- .../pager/reversed/ReversedReaderFragment.kt | 6 ++ .../reader/ui/pager/standard/PageHolder.kt | 1 - .../ui/pager/standard/PagerEventSupplier.kt | 24 ++++++ .../ui/pager/standard/PagerReaderFragment.kt | 5 ++ .../ui/pager/standard/SsivZoomListener.kt | 32 -------- .../ui/pager/webtoon/WebtoonFrameLayout.kt | 4 +- .../ui/pager/webtoon/WebtoonReaderFragment.kt | 12 ++- .../ui/pager/webtoon/WebtoonScalingFrame.kt | 77 +++++++++++++++++-- .../res/layout/fragment_reader_standard.xml | 3 +- .../res/layout/fragment_reader_webtoon.xml | 5 +- app/src/main/res/layout/item_page.xml | 2 + app/src/main/res/layout/item_page_webtoon.xml | 4 +- app/src/main/res/values/dimens.xml | 2 + 18 files changed, 155 insertions(+), 60 deletions(-) create mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerEventSupplier.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/SsivZoomListener.kt diff --git a/app/build.gradle b/app/build.gradle index 76c73a8ae..ad032247d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -132,7 +132,7 @@ dependencies { implementation 'io.coil-kt:coil-base:2.4.0' implementation 'io.coil-kt:coil-svg:2.4.0' - implementation 'com.github.KotatsuApp:subsampling-scale-image-view:9b1d20be67' + implementation 'com.github.KotatsuApp:subsampling-scale-image-view:169806d928' implementation 'com.github.solkin:disk-lru-cache:1.4' implementation 'io.noties.markwon:core:4.6.2' diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 24997fe58..b38e38c99 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -107,7 +107,7 @@ class ReaderActivity : supportActionBar?.setDisplayHomeAsUpEnabled(true) touchHelper = GridTouchHelper(this, this) scrollTimer = scrollTimerFactory.create(this, this) - controlDelegate = ReaderControlDelegate(settings, this, this) + controlDelegate = ReaderControlDelegate(resources, settings, this, this) viewBinding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected) viewBinding.slider.setLabelFormatter(PageLabelFormatter()) ReaderSliderListener(this, viewModel).attachToSlider(viewBinding.slider) @@ -347,8 +347,8 @@ class ReaderActivity : readerManager.currentReader?.switchPageBy(delta) } - override fun scrollBy(delta: Int): Boolean { - return readerManager.currentReader?.scrollBy(delta) ?: false + override fun scrollBy(delta: Int, smooth: Boolean): Boolean { + return readerManager.currentReader?.scrollBy(delta, smooth) ?: false } override fun toggleUiVisibility() { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderControlDelegate.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderControlDelegate.kt index 62c6cd431..a936c8bb2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderControlDelegate.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderControlDelegate.kt @@ -1,16 +1,19 @@ package org.koitharu.kotatsu.reader.ui import android.content.SharedPreferences +import android.content.res.Resources import android.view.KeyEvent import android.view.SoundEffectConstants import android.view.View import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner +import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.core.util.GridTouchHelper class ReaderControlDelegate( + resources: Resources, private val settings: AppSettings, private val listener: OnInteractionListener, owner: LifecycleOwner, @@ -19,6 +22,7 @@ class ReaderControlDelegate( private var isTapSwitchEnabled: Boolean = true private var isVolumeKeysSwitchEnabled: Boolean = false private var isReaderTapsAdaptive: Boolean = true + private var minScrollDelta = resources.getDimensionPixelSize(R.dimen.reader_scroll_delta_min) init { owner.lifecycle.addObserver(this) @@ -82,8 +86,6 @@ class ReaderControlDelegate( KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_PAGE_DOWN, - KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN, - KeyEvent.KEYCODE_DPAD_DOWN, -> { listener.switchPageBy(1) true @@ -95,8 +97,6 @@ class ReaderControlDelegate( } KeyEvent.KEYCODE_PAGE_UP, - KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP, - KeyEvent.KEYCODE_DPAD_UP, -> { listener.switchPageBy(-1) true @@ -112,6 +112,22 @@ class ReaderControlDelegate( true } + KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP, + KeyEvent.KEYCODE_DPAD_UP -> { + if (!listener.scrollBy(-minScrollDelta, smooth = true)) { + listener.switchPageBy(-1) + } + true + } + + KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN, + KeyEvent.KEYCODE_DPAD_DOWN -> { + if (!listener.scrollBy(minScrollDelta, smooth = true)) { + listener.switchPageBy(1) + } + true + } + else -> false } @@ -139,7 +155,7 @@ class ReaderControlDelegate( fun switchPageBy(delta: Int) - fun scrollBy(delta: Int): Boolean + fun scrollBy(delta: Int, smooth: Boolean): Boolean fun toggleUiVisibility() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ScrollTimer.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ScrollTimer.kt index b64161a82..91c0e826d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ScrollTimer.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ScrollTimer.kt @@ -96,7 +96,7 @@ class ScrollTimer @AssistedInject constructor( if (!listener.isReaderResumed()) { continue } - if (!listener.scrollBy(1)) { + if (!listener.scrollBy(1, false)) { accumulator += delayMs } if (accumulator >= pageSwitchDelay) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt index d8b6688be..ac17ceb78 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt @@ -66,7 +66,7 @@ abstract class BaseReaderFragment : BaseFragment() { abstract fun switchPageTo(position: Int, smooth: Boolean) - open fun scrollBy(delta: Int): Boolean = false + open fun scrollBy(delta: Int, smooth: Boolean): Boolean = false abstract fun getCurrentState(): ReaderState? diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt index 7238d99a7..4aae6cefe 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.reader.ui.pager.reversed +import android.os.Build import android.os.Bundle import android.view.InputDevice import android.view.KeyEvent @@ -27,6 +28,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter import org.koitharu.kotatsu.reader.ui.pager.BaseReaderFragment import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.reader.ui.pager.standard.NoAnimPageTransformer +import org.koitharu.kotatsu.reader.ui.pager.standard.PagerEventSupplier import org.koitharu.kotatsu.reader.ui.pager.standard.PagerReaderFragment import javax.inject.Inject import kotlin.math.absoluteValue @@ -54,6 +56,10 @@ class ReversedReaderFragment : BaseReaderFragment offscreenPageLimit = 2 doOnPageChanged(::notifyPageChanged) setOnGenericMotionListener(this@ReversedReaderFragment) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + recyclerView?.defaultFocusHighlightEnabled = false + } + PagerEventSupplier(this).attach() } viewModel.pageAnimation.observe(viewLifecycleOwner) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt index 6842401c1..9c568fad6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt @@ -35,7 +35,6 @@ open class PageHolder( binding.ssiv.bindToLifecycle(owner) binding.ssiv.isEagerLoadingEnabled = !context.isLowRamDevice() binding.ssiv.addOnImageEventListener(delegate) - binding.ssiv.setOnGenericMotionListener(SsivZoomListener()) @Suppress("LeakingThis") bindingInfo.buttonRetry.setOnClickListener(this) @Suppress("LeakingThis") diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerEventSupplier.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerEventSupplier.kt new file mode 100644 index 000000000..9e1cb30bf --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerEventSupplier.kt @@ -0,0 +1,24 @@ +package org.koitharu.kotatsu.reader.ui.pager.standard + +import android.view.KeyEvent +import android.view.View +import android.view.ViewGroup +import androidx.core.view.children +import androidx.viewpager2.widget.ViewPager2 +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import org.koitharu.kotatsu.core.util.ext.recyclerView + +class PagerEventSupplier(private val pager: ViewPager2) : View.OnKeyListener { + + fun attach() { + pager.recyclerView?.setOnKeyListener(this) + } + + override fun onKey(v: View?, keyCode: Int, event: KeyEvent?): Boolean { + val rootView = pager.recyclerView?.findViewHolderForAdapterPosition(pager.currentItem)?.itemView as? ViewGroup + ?: return false + return rootView.children.firstNotNullOfOrNull { x -> + x as? SubsamplingScaleImageView + }?.dispatchKeyEvent(event) == true + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt index a92979509..fb9d9e4e0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.reader.ui.pager.standard +import android.os.Build import android.os.Bundle import android.view.InputDevice import android.view.KeyEvent @@ -55,6 +56,10 @@ class PagerReaderFragment : BaseReaderFragment(), offscreenPageLimit = 2 doOnPageChanged(::notifyPageChanged) setOnGenericMotionListener(this@PagerReaderFragment) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + recyclerView?.defaultFocusHighlightEnabled = false + } + PagerEventSupplier(this).attach() } viewModel.pageAnimation.observe(viewLifecycleOwner) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/SsivZoomListener.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/SsivZoomListener.kt deleted file mode 100644 index fc69d32ad..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/standard/SsivZoomListener.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.koitharu.kotatsu.reader.ui.pager.standard - -import android.graphics.PointF -import android.view.InputDevice -import android.view.KeyEvent -import android.view.MotionEvent -import android.view.View -import android.view.View.OnGenericMotionListener -import android.view.animation.DecelerateInterpolator -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView - -class SsivZoomListener : OnGenericMotionListener { - - override fun onGenericMotion(v: View?, event: MotionEvent): Boolean { - val ssiv = v as? SubsamplingScaleImageView ?: return false - if (event.source and InputDevice.SOURCE_CLASS_POINTER != 0) { - if (event.actionMasked == MotionEvent.ACTION_SCROLL) { - val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL) - val withCtrl = event.metaState and KeyEvent.META_CTRL_MASK != 0 - if (withCtrl || ssiv.scale > ssiv.minScale) { - val center = PointF(event.x, event.y) - val scale = ssiv.scale + axisValue * 1.6f - (ssiv.animateScaleAndCenter(scale, center) ?: return false) - .withInterpolator(DecelerateInterpolator()) - .start() - return true - } - } - } - return false - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonFrameLayout.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonFrameLayout.kt index fe8bcb660..0544f741b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonFrameLayout.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonFrameLayout.kt @@ -12,8 +12,8 @@ class WebtoonFrameLayout @JvmOverloads constructor( @AttrRes defStyleAttr: Int = 0, ) : FrameLayout(context, attrs, defStyleAttr) { - val target by lazy(LazyThreadSafetyMode.NONE) { - findViewById(R.id.ssiv) + val target: WebtoonImageView by lazy(LazyThreadSafetyMode.NONE) { + findViewById(R.id.ssiv) } fun dispatchVerticalScroll(dy: Int): Int { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt index 789f3cc02..1be25bda9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup -import android.view.animation.AccelerateDecelerateInterpolator +import android.view.animation.DecelerateInterpolator import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.async @@ -31,7 +31,7 @@ class WebtoonReaderFragment : BaseReaderFragment() @Inject lateinit var pageLoader: PageLoader - private val scrollInterpolator = AccelerateDecelerateInterpolator() + private val scrollInterpolator = DecelerateInterpolator() override fun onCreateViewBinding( inflater: LayoutInflater, @@ -122,8 +122,12 @@ class WebtoonReaderFragment : BaseReaderFragment() requireViewBinding().recyclerView.firstVisibleItemPosition = position } - override fun scrollBy(delta: Int): Boolean { - requireViewBinding().recyclerView.nestedScrollBy(0, delta) + override fun scrollBy(delta: Int, smooth: Boolean): Boolean { + if (smooth && isAnimationEnabled()) { + requireViewBinding().recyclerView.smoothScrollBy(0, delta, scrollInterpolator) + } else { + requireViewBinding().recyclerView.nestedScrollBy(0, delta) + } return true } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt index ca8a38585..648be1a0c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt @@ -11,14 +11,17 @@ import android.view.InputDevice import android.view.KeyEvent import android.view.MotionEvent import android.view.ScaleGestureDetector +import android.view.ViewConfiguration import android.view.animation.AccelerateDecelerateInterpolator +import android.view.animation.DecelerateInterpolator import android.widget.FrameLayout import android.widget.OverScroller import androidx.core.view.GestureDetectorCompat +import androidx.core.view.ViewConfigurationCompat +import org.koitharu.kotatsu.core.util.ext.getAnimationDuration private const val MAX_SCALE = 2.5f private const val MIN_SCALE = 0.5f -private const val WHEEL_SCALE_FACTOR = 0.2f class WebtoonScalingFrame @JvmOverloads constructor( context: Context, @@ -43,6 +46,7 @@ class WebtoonScalingFrame @JvmOverloads constructor( private var halfHeight = 0f private val translateBounds = RectF() private val targetHitRect = Rect() + private var animator: ValueAnimator? = null var isZoomEnable = true set(value) { @@ -81,13 +85,15 @@ class WebtoonScalingFrame @JvmOverloads constructor( } override fun onGenericMotionEvent(event: MotionEvent): Boolean { - if (event.source and InputDevice.SOURCE_CLASS_POINTER != 0) { + if (isZoomEnable && event.source and InputDevice.SOURCE_CLASS_POINTER != 0) { if (event.actionMasked == MotionEvent.ACTION_SCROLL) { val withCtrl = event.metaState and KeyEvent.META_CTRL_MASK != 0 if (withCtrl) { - val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL) - val newScale = - (scale + axisValue * WHEEL_SCALE_FACTOR).coerceIn(MIN_SCALE, MAX_SCALE) + val axisValue = + event.getAxisValue(MotionEvent.AXIS_VSCROLL) * ViewConfigurationCompat.getScaledVerticalScrollFactor( + ViewConfiguration.get(context), context, + ) + val newScale = (scale + axisValue).coerceIn(MIN_SCALE, MAX_SCALE) scaleChild(newScale, event.x, event.y) return true } @@ -96,6 +102,49 @@ class WebtoonScalingFrame @JvmOverloads constructor( return super.onGenericMotionEvent(event) } + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + if (!isZoomEnable) { + return super.onKeyDown(keyCode, event) + } + return when (keyCode) { + KeyEvent.KEYCODE_ZOOM_IN, + KeyEvent.KEYCODE_NUMPAD_ADD, + KeyEvent.KEYCODE_PLUS -> { + smoothScaleTo(scale * 1.1f) + true + } + + KeyEvent.KEYCODE_ZOOM_OUT, + KeyEvent.KEYCODE_NUMPAD_SUBTRACT, + KeyEvent.KEYCODE_MINUS -> { + smoothScaleTo(scale * 0.9f) + true + } + + KeyEvent.KEYCODE_ESCAPE -> { + smoothScaleTo(1f) + true + } + + else -> super.onKeyDown(keyCode, event) + } + } + + override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { + return if (isZoomEnable) { + keyCode == KeyEvent.KEYCODE_NUMPAD_ADD + || keyCode == KeyEvent.KEYCODE_PLUS + || keyCode == KeyEvent.KEYCODE_NUMPAD_SUBTRACT + || keyCode == KeyEvent.KEYCODE_MINUS + || keyCode == KeyEvent.KEYCODE_ZOOM_IN + || keyCode == KeyEvent.KEYCODE_ZOOM_OUT + || keyCode == KeyEvent.KEYCODE_ESCAPE + || super.onKeyUp(keyCode, event) + } else { + super.onKeyUp(keyCode, event) + } + } + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) halfWidth = w / 2f @@ -173,10 +222,24 @@ class WebtoonScalingFrame @JvmOverloads constructor( return true } - override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true + override fun onScaleBegin(detector: ScaleGestureDetector): Boolean { + animator?.cancel() + animator = null + return true + } override fun onScaleEnd(p0: ScaleGestureDetector) = Unit + private fun smoothScaleTo(target: Float) { + val newScale = target.coerceIn(MIN_SCALE, MAX_SCALE) + animator?.cancel() + animator = ValueAnimator.ofFloat(scale, newScale).apply { + setDuration(context.getAnimationDuration(android.R.integer.config_shortAnimTime)) + interpolator = DecelerateInterpolator() + addUpdateListener { scaleChild(it.animatedValue as Float, halfWidth, halfHeight) } + start() + } + } private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable { @@ -231,7 +294,7 @@ class WebtoonScalingFrame @JvmOverloads constructor( if (overScroller.computeScrollOffset()) { transformMatrix.postTranslate( overScroller.currX - transX, - overScroller.currY - transY + overScroller.currY - transY, ) invalidateTarget() postOnAnimation(this) diff --git a/app/src/main/res/layout/fragment_reader_standard.xml b/app/src/main/res/layout/fragment_reader_standard.xml index dce13cd82..0d062a836 100644 --- a/app/src/main/res/layout/fragment_reader_standard.xml +++ b/app/src/main/res/layout/fragment_reader_standard.xml @@ -3,4 +3,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pager" android:layout_width="match_parent" - android:layout_height="match_parent" /> \ No newline at end of file + android:layout_height="match_parent" + android:defaultFocusHighlightEnabled="false" /> diff --git a/app/src/main/res/layout/fragment_reader_webtoon.xml b/app/src/main/res/layout/fragment_reader_webtoon.xml index 5a0960782..a45ab81de 100644 --- a/app/src/main/res/layout/fragment_reader_webtoon.xml +++ b/app/src/main/res/layout/fragment_reader_webtoon.xml @@ -4,12 +4,15 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/frame" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:focusable="true" + android:defaultFocusHighlightEnabled="false"> diff --git a/app/src/main/res/layout/item_page.xml b/app/src/main/res/layout/item_page.xml index 6100fb225..3909ca1bb 100644 --- a/app/src/main/res/layout/item_page.xml +++ b/app/src/main/res/layout/item_page.xml @@ -10,6 +10,8 @@ android:id="@+id/ssiv" android:layout_width="match_parent" android:layout_height="match_parent" + android:defaultFocusHighlightEnabled="false" + android:focusable="true" app:restoreStrategy="deferred" /> + android:layout_height="wrap_content" + android:defaultFocusHighlightEnabled="false"> 6dp 400dp + + 200dp