Fix reader fullscreen mode

This commit is contained in:
Koitharu
2020-02-21 19:20:42 +02:00
parent 2dc5840872
commit 25b828cf83
6 changed files with 196 additions and 19 deletions

View File

@@ -3,7 +3,6 @@ package org.koitharu.kotatsu.ui.common
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.WindowManager
abstract class BaseFullscreenActivity : BaseActivity() {
@@ -11,7 +10,7 @@ abstract class BaseFullscreenActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
with(window) {
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
statusBarColor = Color.TRANSPARENT
navigationBarColor = Color.TRANSPARENT
}
@@ -19,18 +18,20 @@ abstract class BaseFullscreenActivity : BaseActivity() {
}
protected fun hideSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
)
}
protected fun showSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
window.decorView.systemUiVisibility =
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
}

View File

@@ -18,9 +18,8 @@ import org.koitharu.kotatsu.core.model.MangaHistory
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.common.BaseFullscreenActivity
import org.koitharu.kotatsu.utils.GridTouchHelper
import org.koitharu.kotatsu.utils.ext.hasGlobalPoint
import org.koitharu.kotatsu.utils.ext.hitTest
import org.koitharu.kotatsu.utils.ext.showDialog
import org.koitharu.kotatsu.utils.anim.Motion
import org.koitharu.kotatsu.utils.ext.*
class ReaderActivity : BaseFullscreenActivity(), ReaderView, GridTouchHelper.OnGridTouchListener {
@@ -113,12 +112,12 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, GridTouchHelper.OnG
when (area) {
GridTouchHelper.AREA_CENTER -> {
if (appbar_top.isVisible) {
appbar_top.isVisible = false
appbar_bottom.isVisible = false
appbar_top.hideAnimated(Motion.SlideTop)
appbar_bottom.hideAnimated(Motion.SlideBottom)
hideSystemUI()
} else {
appbar_top.isVisible = true
appbar_bottom.isVisible = true
appbar_top.showAnimated(Motion.SlideTop)
appbar_bottom.showAnimated(Motion.SlideBottom)
showSystemUI()
}
}

View File

@@ -0,0 +1,9 @@
package org.koitharu.kotatsu.utils.anim
import androidx.annotation.IntegerRes
enum class Duration(@IntegerRes val resId: Int) {
SHORT(android.R.integer.config_shortAnimTime),
MEDIUM(android.R.integer.config_mediumAnimTime),
LONG(android.R.integer.config_longAnimTime)
}

View File

@@ -0,0 +1,95 @@
package org.koitharu.kotatsu.utils.anim
import android.view.View
import android.view.ViewPropertyAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import org.koitharu.kotatsu.utils.ext.measureHeight
sealed class Motion {
abstract fun reset(v: View)
abstract fun hideView(v: View)
abstract fun hide(v: View, anim: ViewPropertyAnimator)
abstract fun show(v: View, anim: ViewPropertyAnimator)
object CrossFade : Motion() {
override fun reset(v: View) {
v.alpha = 1f
}
override fun hideView(v: View) {
v.alpha = 0f
}
override fun hide(v: View, anim: ViewPropertyAnimator) {
anim.alpha(0f)
}
override fun show(v: View, anim: ViewPropertyAnimator) {
anim.alpha(1f)
}
}
object SlideBottom : Motion() {
override fun reset(v: View) {
v.translationY = 0f
}
override fun hideView(v: View) {
v.translationY = v.measureHeight().toFloat()
}
override fun hide(v: View, anim: ViewPropertyAnimator) {
anim.translationY(v.measureHeight().toFloat())
}
override fun show(v: View, anim: ViewPropertyAnimator) {
anim.translationY(0f)
}
}
object SlideTop : Motion() {
override fun reset(v: View) {
v.translationY = 0f
}
override fun hideView(v: View) {
v.translationY = -v.measureHeight().toFloat()
}
override fun hide(v: View, anim: ViewPropertyAnimator) {
anim.translationY(-v.measureHeight().toFloat())
}
override fun show(v: View, anim: ViewPropertyAnimator) {
anim.translationY(0f)
}
}
object CheckEffect : Motion() {
override fun reset(v: View) {
v.scaleX = 1f
v.scaleY = 1f
}
override fun hideView(v: View) {
v.scaleX = 0f
v.scaleY = 0f
}
override fun hide(v: View, anim: ViewPropertyAnimator) {
anim.scaleX(0f)
anim.scaleY(0f)
anim.interpolator = AccelerateDecelerateInterpolator()
}
override fun show(v: View, anim: ViewPropertyAnimator) {
anim.scaleY(1f)
anim.scaleX(1f)
anim.interpolator = AccelerateDecelerateInterpolator()
}
}
}

View File

@@ -0,0 +1,57 @@
package org.koitharu.kotatsu.utils.ext
import android.view.View
import org.koitharu.kotatsu.utils.anim.Duration
import org.koitharu.kotatsu.utils.anim.Motion
fun View.showAnimated(
effect: Motion,
duration: Duration = Duration.MEDIUM,
onDone: (() -> Unit)? = null
) {
if (this.visibility == View.VISIBLE) {
onDone?.invoke()
return
}
this.clearAnimation()
effect.hideView(this)
this.visibility = View.VISIBLE
this.animate().also {
it.duration = context.resources.getInteger(duration.resId).toLong()
effect.show(this, it)
}.withEndAction(onDone)
.start()
}
fun View.hideAnimated(
effect: Motion,
duration: Duration = Duration.MEDIUM,
onDone: (() -> Unit)? = null
) {
if (this.visibility != View.VISIBLE) {
onDone?.invoke()
return
}
this.clearAnimation()
this.animate().also {
it.duration = context.resources.getInteger(duration.resId).toLong()
effect.hide(this, it)
}.withEndAction {
this.visibility = View.GONE
effect.reset(this)
onDone?.invoke()
}.start()
}
fun View.showOrHideAnimated(
predicate: Boolean,
effect: Motion,
duration: Duration = Duration.MEDIUM,
onDone: (() -> Unit)? = null
) {
if (predicate) {
showAnimated(effect, duration, onDone)
} else {
hideAnimated(effect, duration, onDone)
}
}

View File

@@ -140,4 +140,20 @@ fun DrawerLayout.toggleDrawer(gravity: Int) {
} else {
openDrawer(gravity)
}
}
}
fun View.measureHeight(): Int {
val vh = height
return if (vh == 0) {
measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
measuredHeight
} else vh
}
fun View.measureWidth(): Int {
val vw = width
return if (vw == 0) {
measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
measuredWidth
} else vw
}