Merge pull request #3373 from nextcloud/technicalDebt/#3372

Remove use of setSystemUiVisibility in previews #3372
This commit is contained in:
Marcel Hibbe 2023-10-11 14:54:49 +02:00 committed by GitHub
commit 3b4a9451f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 161 additions and 88 deletions

View File

@ -32,8 +32,15 @@ import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import com.google.android.material.snackbar.Snackbar
import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
@ -45,7 +52,7 @@ import java.io.File
class FullScreenImageActivity : AppCompatActivity() {
lateinit var binding: ActivityFullScreenImageBinding
private lateinit var windowInsetsController: WindowInsetsControllerCompat
private lateinit var path: String
private var showFullscreen = false
@ -55,27 +62,31 @@ class FullScreenImageActivity : AppCompatActivity() {
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == android.R.id.home) {
onBackPressedDispatcher.onBackPressed()
true
} else if (item.itemId == R.id.share) {
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
)
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
type = IMAGE_PREFIX_GENERIC
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
return when (item.itemId) {
android.R.id.home -> {
onBackPressedDispatcher.onBackPressed()
true
}
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
R.id.share -> {
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
)
true
} else {
super.onOptionsItemSelected(item)
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
type = IMAGE_PREFIX_GENERIC
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
@ -86,8 +97,10 @@ class FullScreenImageActivity : AppCompatActivity() {
setContentView(binding.root)
setSupportActionBar(binding.imageviewToolbar)
binding.photoView.setOnPhotoTapListener { view, x, y ->
WindowCompat.setDecorFitsSystemWindows(window, false)
initWindowInsetsController()
applyWindowInsets()
binding.photoView.setOnPhotoTapListener { _, _, _ ->
toggleFullscreen()
}
binding.photoView.setOnOutsidePhotoTapListener {
@ -142,35 +155,41 @@ class FullScreenImageActivity : AppCompatActivity() {
private fun toggleFullscreen() {
showFullscreen = !showFullscreen
if (showFullscreen) {
hideSystemUI()
supportActionBar?.hide()
enterImmersiveMode()
} else {
showSystemUI()
supportActionBar?.show()
exitImmersiveMode()
}
}
private fun hideSystemUI() {
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE
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
)
private fun initWindowInsetsController() {
windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
private 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
)
private fun enterImmersiveMode() {
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
supportActionBar?.hide()
}
private fun exitImmersiveMode() {
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
supportActionBar?.show()
}
private fun applyWindowInsets() {
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
val insets =
windowInsets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
binding.imageviewToolbar.updateLayoutParams<MarginLayoutParams> {
topMargin = insets.top
}
binding.imageviewToolbar.updatePadding(left = insets.left, right = insets.right)
WindowInsetsCompat.CONSUMED
}
}
companion object {
private val TAG = "FullScreenImageActivity"
private const val TAG = "FullScreenImageActivity"
private const val HUNDRED_MB = 100 * 1024 * 1024
private const val MAX_SCALE = 6.0f
private const val MEDIUM_SCALE = 2.45f

View File

@ -30,14 +30,23 @@ import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.view.WindowManager
import android.widget.FrameLayout
import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.marginBottom
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.DefaultTimeBar
import androidx.media3.ui.PlayerView
import autodagger.AutoInjector
import com.nextcloud.talk.BuildConfig
@ -56,6 +65,7 @@ class FullScreenMediaActivity : AppCompatActivity() {
private var playWhenReadyState: Boolean = true
private var playBackPosition: Long = 0L
private lateinit var windowInsetsController: WindowInsetsControllerCompat
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_preview, menu)
@ -63,34 +73,38 @@ class FullScreenMediaActivity : AppCompatActivity() {
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == android.R.id.home) {
onBackPressedDispatcher.onBackPressed()
true
} else if (item.itemId == R.id.share) {
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
)
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
type = VIDEO_PREFIX_GENERIC
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
return when (item.itemId) {
android.R.id.home -> {
onBackPressedDispatcher.onBackPressed()
true
}
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
R.id.share -> {
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
)
true
} else {
super.onOptionsItemSelected(item)
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
type = VIDEO_PREFIX_GENERIC
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
@OptIn(UnstableApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
val fileName = intent.getStringExtra("FILE_NAME")
val isAudioOnly = intent.getBooleanExtra("AUDIO_ONLY", false)
@ -110,14 +124,15 @@ class FullScreenMediaActivity : AppCompatActivity() {
binding.playerView.controllerShowTimeoutMs = 0
}
initWindowInsetsController()
applyWindowInsets()
binding.playerView.setControllerVisibilityListener(
PlayerView.ControllerVisibilityListener { v ->
if (v != 0) {
hideSystemUI()
supportActionBar?.hide()
enterImmersiveMode()
} else {
showSystemUI()
supportActionBar?.show()
exitImmersiveMode()
}
}
)
@ -158,22 +173,44 @@ class FullScreenMediaActivity : AppCompatActivity() {
player = null
}
private fun hideSystemUI() {
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE
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
)
private fun initWindowInsetsController() {
windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
private 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
private fun enterImmersiveMode() {
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
supportActionBar?.hide()
}
private fun exitImmersiveMode() {
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
supportActionBar?.show()
}
private fun applyWindowInsets() {
val playerView = binding.playerView
val exoControls = playerView.findViewById<FrameLayout>(R.id.exo_bottom_bar)
val exoProgress = playerView.findViewById<DefaultTimeBar>(R.id.exo_progress)
val progressBottomMargin = exoProgress.marginBottom
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
val insets = windowInsets.getInsets(
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type
.displayCutout()
)
binding.mediaviewToolbar.updateLayoutParams<MarginLayoutParams> {
topMargin = insets.top
}
exoControls.updateLayoutParams<MarginLayoutParams> {
bottomMargin = insets.bottom
}
exoProgress.updateLayoutParams<MarginLayoutParams> {
bottomMargin = insets.bottom + progressBottomMargin
}
exoControls.updatePadding(left = insets.left, right = insets.right)
exoProgress.updatePadding(left = insets.left, right = insets.right)
binding.mediaviewToolbar.updatePadding(left = insets.left, right = insets.right)
WindowInsetsCompat.CONSUMED
}
}
}

View File

@ -28,7 +28,6 @@
android:id="@+id/image_wrapper_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.FullScreenImageActivity">
<com.google.android.material.appbar.MaterialToolbar

View File

@ -25,7 +25,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.FullScreenMediaActivity">
<androidx.appcompat.widget.Toolbar

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="FullScreenImageTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/black</item>
<item name="android:navigationBarColor">@color/transparent</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<style name="FullScreenMediaTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/black</item>
<item name="android:navigationBarColor">@color/black</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
</resources>

View File

@ -217,20 +217,18 @@
<style name="FullScreenImageTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/black</item>
<item name="android:navigationBarColor">@color/black</item>
<item name="android:navigationBarColor">@color/transparent</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="FullScreenMediaTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/black</item>
<item name="android:navigationBarColor">@color/black</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="TextInputLayoutTheme" parent="Theme.AppCompat">