Merge branch 'chenxiaolong-landscape-insets' into develop

This commit is contained in:
J-Jamet
2025-10-06 13:58:39 +02:00
7 changed files with 106 additions and 55 deletions

View File

@@ -1,4 +1,4 @@
name: Bug Report name: Bug report
description: Report a bug. description: Report a bug.
labels: ["bug"] labels: ["bug"]
body: body:

View File

@@ -23,7 +23,6 @@ import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@@ -38,13 +37,10 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat import androidx.core.graphics.BlendModeCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
@@ -83,11 +79,13 @@ import com.kunzisoft.keepass.view.hideByFading
import com.kunzisoft.keepass.view.setTransparentNavigationBar import com.kunzisoft.keepass.view.setTransparentNavigationBar
import com.kunzisoft.keepass.view.showActionErrorIfNeeded import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.viewmodels.EntryViewModel import com.kunzisoft.keepass.viewmodels.EntryViewModel
import java.util.EnumSet
import java.util.UUID import java.util.UUID
class EntryActivity : DatabaseLockActivity() { class EntryActivity : DatabaseLockActivity() {
private var footer: ViewGroup? = null private var footer: ViewGroup? = null
private var container: View? = null
private var coordinatorLayout: CoordinatorLayout? = null private var coordinatorLayout: CoordinatorLayout? = null
private var collapsingToolbarLayout: CollapsingToolbarLayout? = null private var collapsingToolbarLayout: CollapsingToolbarLayout? = null
private var appBarLayout: AppBarLayout? = null private var appBarLayout: AppBarLayout? = null
@@ -139,6 +137,7 @@ class EntryActivity : DatabaseLockActivity() {
// Get views // Get views
footer = findViewById(R.id.activity_entry_footer) footer = findViewById(R.id.activity_entry_footer)
container = findViewById(R.id.activity_entry_container)
coordinatorLayout = findViewById(R.id.toolbar_coordinator) coordinatorLayout = findViewById(R.id.toolbar_coordinator)
collapsingToolbarLayout = findViewById(R.id.toolbar_layout) collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
appBarLayout = findViewById(R.id.app_bar) appBarLayout = findViewById(R.id.app_bar)
@@ -154,8 +153,12 @@ class EntryActivity : DatabaseLockActivity() {
setTransparentNavigationBar { setTransparentNavigationBar {
// To fix margin with API 27 // To fix margin with API 27
ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout!!, null) ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout!!, null)
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP) container?.applyWindowInsets(EnumSet.of(
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM) WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
} }
// Empty title // Empty title

View File

@@ -100,6 +100,7 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.view.updateLockPaddingStart import com.kunzisoft.keepass.view.updateLockPaddingStart
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
import java.util.EnumSet
import java.util.UUID import java.util.UUID
class EntryEditActivity : DatabaseLockActivity(), class EntryEditActivity : DatabaseLockActivity(),
@@ -180,8 +181,12 @@ class EntryEditActivity : DatabaseLockActivity(),
// To apply fit window with transparency // To apply fit window with transparency
setTransparentNavigationBar(applyToStatusBar = true) { setTransparentNavigationBar(applyToStatusBar = true) {
container?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME) container?.applyWindowInsets(EnumSet.of(
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME) WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
} }
stopService(Intent(this, ClipboardEntryNotificationService::class.java)) stopService(Intent(this, ClipboardEntryNotificationService::class.java))

View File

@@ -48,6 +48,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
@@ -117,6 +118,7 @@ import com.kunzisoft.keepass.view.updateLockPaddingStart
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
import com.kunzisoft.keepass.viewmodels.GroupViewModel import com.kunzisoft.keepass.viewmodels.GroupViewModel
import org.joda.time.LocalDateTime import org.joda.time.LocalDateTime
import java.util.EnumSet
class GroupActivity : DatabaseLockActivity(), class GroupActivity : DatabaseLockActivity(),
@@ -131,6 +133,7 @@ class GroupActivity : DatabaseLockActivity(),
private var header: ViewGroup? = null private var header: ViewGroup? = null
private var footer: ViewGroup? = null private var footer: ViewGroup? = null
private var drawerLayout: DrawerLayout? = null private var drawerLayout: DrawerLayout? = null
private var constraintLayout: ConstraintLayout? = null
private var databaseNavView: NavigationDatabaseView? = null private var databaseNavView: NavigationDatabaseView? = null
private var coordinatorLayout: CoordinatorLayout? = null private var coordinatorLayout: CoordinatorLayout? = null
private var coordinatorError: CoordinatorLayout? = null private var coordinatorError: CoordinatorLayout? = null
@@ -279,6 +282,7 @@ class GroupActivity : DatabaseLockActivity(),
header = findViewById(R.id.activity_group_header) header = findViewById(R.id.activity_group_header)
footer = findViewById(R.id.activity_group_footer) footer = findViewById(R.id.activity_group_footer)
drawerLayout = findViewById(R.id.drawer_layout) drawerLayout = findViewById(R.id.drawer_layout)
constraintLayout = findViewById(R.id.activity_group_container_view)
databaseNavView = findViewById(R.id.database_nav_view) databaseNavView = findViewById(R.id.database_nav_view)
coordinatorLayout = findViewById(R.id.group_coordinator) coordinatorLayout = findViewById(R.id.group_coordinator)
coordinatorError = findViewById(R.id.error_coordinator) coordinatorError = findViewById(R.id.error_coordinator)
@@ -296,8 +300,19 @@ class GroupActivity : DatabaseLockActivity(),
// To apply fit window with transparency // To apply fit window with transparency
setTransparentNavigationBar(applyToStatusBar = true) { setTransparentNavigationBar(applyToStatusBar = true) {
drawerLayout?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME) constraintLayout?.applyWindowInsets(EnumSet.of(
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME) WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
// The background of the drawer is meant to overlap system bars, so use padding
databaseNavView?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_PADDING,
WindowInsetPosition.BOTTOM_PADDING,
// Only on the start side, since the drawer is anchored to one side of the screen
WindowInsetPosition.START_PADDING,
))
} }
lockView?.setOnClickListener { lockView?.setOnClickListener {

View File

@@ -70,8 +70,12 @@ open class SettingsActivity
// To apply navigation bar with background color // To apply navigation bar with background color
/* TODO Settings nav bar /* TODO Settings nav bar
setTransparentNavigationBar { setTransparentNavigationBar {
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP) coordinatorLayout?.applyWindowInsets(EnumSet.of(
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM) WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
}*/ }*/
mExternalFileHelper = ExternalFileHelper(this) mExternalFileHelper = ExternalFileHelper(this)

View File

@@ -24,7 +24,6 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
import android.graphics.PorterDuff import android.graphics.PorterDuff
@@ -58,7 +57,6 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.forEach import androidx.core.view.forEach
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.core.view.updatePaddingRelative import androidx.core.view.updatePaddingRelative
import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@@ -66,6 +64,7 @@ import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.helper.getLocalizedMessage import com.kunzisoft.keepass.database.helper.getLocalizedMessage
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import java.util.EnumSet
/** /**
@@ -306,9 +305,7 @@ fun CollapsingToolbarLayout.changeTitleColor(color: Int) {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, applyWindowInsets: () -> Unit) { fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, applyWindowInsets: () -> Unit) {
// Only in portrait if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
&& resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
window.navigationBarColor = ContextCompat.getColor(this, R.color.surface_selector) window.navigationBarColor = ContextCompat.getColor(this, R.color.surface_selector)
if (applyToStatusBar) { if (applyToStatusBar) {
@@ -324,7 +321,7 @@ fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, appl
/** /**
* Apply a margin to a view to fix the window inset * Apply a margin to a view to fix the window inset
*/ */
fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.BOTTOM) { fun View.applyWindowInsets(positions: EnumSet<WindowInsetPosition>) {
ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets ->
var consumed = false var consumed = false
@@ -340,52 +337,78 @@ fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.B
} }
} }
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()
when (position) { or WindowInsetsCompat.Type.displayCutout()
WindowInsetPosition.TOP -> { or WindowInsetsCompat.Type.ime())
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> { val isRtl = layoutDirection == View.LAYOUT_DIRECTION_RTL
topMargin = insets.top
val wantTopMargins = positions.contains(WindowInsetPosition.TOP_MARGINS)
val wantBottomMargins = positions.contains(WindowInsetPosition.BOTTOM_MARGINS)
val wantStartMargins = positions.contains(WindowInsetPosition.START_MARGINS)
val wantEndMargins = positions.contains(WindowInsetPosition.END_MARGINS)
if (view.layoutParams is ViewGroup.MarginLayoutParams
&& (wantTopMargins || wantBottomMargins || wantStartMargins || wantEndMargins)) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
if (wantTopMargins) {
topMargin = insets.top
}
if (wantBottomMargins) {
bottomMargin = insets.bottom
}
if (wantStartMargins) {
if (isRtl) {
rightMargin = insets.right
} else {
leftMargin = insets.left
} }
} }
} if (wantEndMargins) {
WindowInsetPosition.LEGIT_TOP -> { if (isRtl) {
if (view.layoutParams is ViewGroup.MarginLayoutParams) { leftMargin = insets.left
view.updateLayoutParams<ViewGroup.MarginLayoutParams> { } else {
topMargin = 0 rightMargin = insets.right
}
}
}
WindowInsetPosition.BOTTOM -> {
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = insets.bottom
}
}
}
WindowInsetPosition.BOTTOM_IME -> {
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = if (imeHeight > 1) 0 else insets.bottom
}
}
}
WindowInsetPosition.TOP_BOTTOM_IME -> {
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
bottomMargin = if (imeHeight > 1) imeHeight else 0
} }
} }
} }
} }
val wantTopPadding = positions.contains(WindowInsetPosition.TOP_PADDING)
val wantBottomPadding = positions.contains(WindowInsetPosition.BOTTOM_PADDING)
val wantStartPadding = positions.contains(WindowInsetPosition.START_PADDING)
val wantEndPadding = positions.contains(WindowInsetPosition.END_PADDING)
if (wantTopPadding || wantBottomPadding || wantStartPadding || wantEndPadding) {
val topPadding = if (wantTopPadding) insets.top else 0
val bottomPadding = if (wantBottomPadding) insets.bottom else 0
var leftPadding = 0
var rightPadding = 0
if (wantStartPadding) {
if (isRtl) {
rightPadding = insets.right
} else {
leftPadding = insets.left
}
}
if (wantEndPadding) {
if (isRtl) {
leftPadding = insets.left
} else {
rightPadding = insets.right
}
}
setPadding(leftPadding, topPadding, rightPadding, bottomPadding)
}
// If any of the children consumed the insets, return an appropriate value // If any of the children consumed the insets, return an appropriate value
if (consumed) WindowInsetsCompat.CONSUMED else windowInsets if (consumed) WindowInsetsCompat.CONSUMED else windowInsets
} }
} }
enum class WindowInsetPosition { enum class WindowInsetPosition {
TOP, BOTTOM, LEGIT_TOP, BOTTOM_IME, TOP_BOTTOM_IME TOP_MARGINS, BOTTOM_MARGINS, START_MARGINS, END_MARGINS,
TOP_PADDING, BOTTOM_PADDING, START_PADDING, END_PADDING,
} }

View File

@@ -20,6 +20,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_entry_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"> android:filterTouchesWhenObscured="true">