Fix reader fullscreen mode
This commit is contained in:
@@ -3,7 +3,6 @@ package org.koitharu.kotatsu.ui.common
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
|
||||||
|
|
||||||
|
|
||||||
abstract class BaseFullscreenActivity : BaseActivity() {
|
abstract class BaseFullscreenActivity : BaseActivity() {
|
||||||
@@ -11,7 +10,7 @@ abstract class BaseFullscreenActivity : BaseActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
with(window) {
|
with(window) {
|
||||||
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
// addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||||
statusBarColor = Color.TRANSPARENT
|
statusBarColor = Color.TRANSPARENT
|
||||||
navigationBarColor = Color.TRANSPARENT
|
navigationBarColor = Color.TRANSPARENT
|
||||||
}
|
}
|
||||||
@@ -19,18 +18,20 @@ abstract class BaseFullscreenActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun hideSystemUI() {
|
protected fun hideSystemUI() {
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
window.decorView.systemUiVisibility = (
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
|
||||||
or View.SYSTEM_UI_FLAG_FULLSCREEN)
|
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
|
||||||
|
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun showSystemUI() {
|
protected fun showSystemUI() {
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
window.decorView.systemUiVisibility =
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
(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_LAYOUT_FULLSCREEN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,9 +18,8 @@ import org.koitharu.kotatsu.core.model.MangaHistory
|
|||||||
import org.koitharu.kotatsu.core.model.MangaPage
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
import org.koitharu.kotatsu.ui.common.BaseFullscreenActivity
|
import org.koitharu.kotatsu.ui.common.BaseFullscreenActivity
|
||||||
import org.koitharu.kotatsu.utils.GridTouchHelper
|
import org.koitharu.kotatsu.utils.GridTouchHelper
|
||||||
import org.koitharu.kotatsu.utils.ext.hasGlobalPoint
|
import org.koitharu.kotatsu.utils.anim.Motion
|
||||||
import org.koitharu.kotatsu.utils.ext.hitTest
|
import org.koitharu.kotatsu.utils.ext.*
|
||||||
import org.koitharu.kotatsu.utils.ext.showDialog
|
|
||||||
|
|
||||||
class ReaderActivity : BaseFullscreenActivity(), ReaderView, GridTouchHelper.OnGridTouchListener {
|
class ReaderActivity : BaseFullscreenActivity(), ReaderView, GridTouchHelper.OnGridTouchListener {
|
||||||
|
|
||||||
@@ -113,12 +112,12 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, GridTouchHelper.OnG
|
|||||||
when (area) {
|
when (area) {
|
||||||
GridTouchHelper.AREA_CENTER -> {
|
GridTouchHelper.AREA_CENTER -> {
|
||||||
if (appbar_top.isVisible) {
|
if (appbar_top.isVisible) {
|
||||||
appbar_top.isVisible = false
|
appbar_top.hideAnimated(Motion.SlideTop)
|
||||||
appbar_bottom.isVisible = false
|
appbar_bottom.hideAnimated(Motion.SlideBottom)
|
||||||
hideSystemUI()
|
hideSystemUI()
|
||||||
} else {
|
} else {
|
||||||
appbar_top.isVisible = true
|
appbar_top.showAnimated(Motion.SlideTop)
|
||||||
appbar_bottom.isVisible = true
|
appbar_bottom.showAnimated(Motion.SlideBottom)
|
||||||
showSystemUI()
|
showSystemUI()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
95
app/src/main/java/org/koitharu/kotatsu/utils/anim/Motion.kt
Normal file
95
app/src/main/java/org/koitharu/kotatsu/utils/anim/Motion.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
57
app/src/main/java/org/koitharu/kotatsu/utils/ext/AnimExt.kt
Normal file
57
app/src/main/java/org/koitharu/kotatsu/utils/ext/AnimExt.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -140,4 +140,20 @@ fun DrawerLayout.toggleDrawer(gravity: Int) {
|
|||||||
} else {
|
} else {
|
||||||
openDrawer(gravity)
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user