Skip to content

Commit 91a8a8d

Browse files
committed
fix: adapt screens to infinite edges feature
1 parent 36ef69e commit 91a8a8d

18 files changed

Lines changed: 207 additions & 40 deletions

‎owncloudApp/src/main/java/com/owncloud/android/extensions/ActivityExt.kt‎

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
*
44
* @author David González Verdugo
55
* @author Aitor Ballesteros Pavón
6+
* @author Jorge Aguado Recio
67
*
7-
* Copyright (C) 2024 ownCloud GmbH.
8+
* Copyright (C) 2026 ownCloud GmbH.
89
*
910
* This program is free software: you can redistribute it and/or modify
1011
* it under the terms of the GNU General Public License version 2,
@@ -32,14 +33,21 @@ import android.content.pm.ResolveInfo
3233
import android.net.Uri
3334
import android.text.method.LinkMovementMethod
3435
import android.util.TypedValue
36+
import android.view.View
37+
import android.view.ViewGroup
3538
import android.view.inputmethod.InputMethodManager
3639
import android.webkit.MimeTypeMap
3740
import android.widget.LinearLayout
3841
import android.widget.TextView
3942
import android.widget.Toast
4043
import androidx.appcompat.app.AppCompatActivity
44+
import androidx.appcompat.widget.Toolbar
4145
import androidx.core.content.FileProvider
4246
import androidx.core.text.HtmlCompat
47+
import androidx.core.view.ViewCompat
48+
import androidx.core.view.WindowInsetsCompat
49+
import androidx.core.view.updateLayoutParams
50+
import androidx.core.view.updateMargins
4351
import androidx.fragment.app.FragmentActivity
4452
import androidx.lifecycle.Lifecycle
4553
import androidx.lifecycle.lifecycleScope
@@ -74,6 +82,7 @@ import kotlinx.coroutines.launch
7482
import org.koin.android.ext.android.inject
7583
import timber.log.Timber
7684
import java.io.File
85+
import kotlin.math.min
7786

7887
fun Activity.showErrorInSnackbar(genericErrorMessageId: Int, throwable: Throwable?) =
7988
throwable?.let {
@@ -495,3 +504,41 @@ fun <T> FragmentActivity.collectLatestLifecycleFlow(
495504
}
496505
}
497506
}
507+
508+
fun Activity.adaptInfiniteEdges(root: View) {
509+
val typedValue = TypedValue()
510+
var actionBarHeight = 0
511+
if (theme.resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
512+
actionBarHeight = TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)
513+
}
514+
515+
val maxInsetPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32f, resources.displayMetrics).toInt()
516+
val extraTopPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12f, resources.displayMetrics).toInt()
517+
518+
// Adapt toolbar for infinite edges
519+
findViewById<View>(R.id.toolbar).apply {
520+
ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
521+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
522+
val usedInsetFinal = min(systemInsets.top, maxInsetPx) + extraTopPx
523+
updateLayoutParams { height = actionBarHeight + usedInsetFinal }
524+
insets
525+
}
526+
}
527+
528+
// Adapt text in the toolbar
529+
findViewById<Toolbar>(R.id.standard_toolbar).apply {
530+
ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
531+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
532+
val usedInsetFinal = min(systemInsets.top, maxInsetPx) + extraTopPx
533+
updateLayoutParams<ViewGroup.MarginLayoutParams> { updateMargins(top = usedInsetFinal) }
534+
insets
535+
}
536+
}
537+
538+
// Adapt content for infinite edges
539+
ViewCompat.setOnApplyWindowInsetsListener(root) { _, insets ->
540+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
541+
root.setPadding(systemInsets.left, root.paddingTop, systemInsets.right, systemInsets.bottom)
542+
insets
543+
}
544+
}

‎owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* @author Jorge Aguado Recio
1313
*
1414
* Copyright (C) 2012 Bartek Przybylski
15-
* Copyright (C) 2025 ownCloud GmbH.
15+
* Copyright (C) 2026 ownCloud GmbH.
1616
*
1717
* This program is free software: you can redistribute it and/or modify
1818
* it under the terms of the GNU General Public License version 2,
@@ -43,6 +43,8 @@ import android.view.WindowManager.LayoutParams.FLAG_SECURE
4343
import androidx.appcompat.app.AppCompatActivity
4444
import androidx.browser.customtabs.CustomTabsIntent
4545
import androidx.core.net.toUri
46+
import androidx.core.view.ViewCompat
47+
import androidx.core.view.WindowInsetsCompat
4648
import androidx.core.view.isVisible
4749
import androidx.core.widget.doAfterTextChanged
4850
import com.owncloud.android.BuildConfig
@@ -144,6 +146,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
144146
// UI initialization
145147
binding = AccountSetupBinding.inflate(layoutInflater)
146148
val view = binding.root
149+
adaptInfiniteEdges()
147150
setContentView(view)
148151

149152
if (loginAction != ACTION_CREATE) {
@@ -920,4 +923,12 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
920923
override fun optionLockSelected(type: LockType) {
921924
manageOptionLockSelected(type)
922925
}
926+
927+
private fun adaptInfiniteEdges() {
928+
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
929+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
930+
binding.loginLayout.setPadding(systemInsets.left, 0, systemInsets.right, systemInsets.bottom)
931+
insets
932+
}
933+
}
923934
}

‎owncloudApp/src/main/java/com/owncloud/android/presentation/releasenotes/ReleaseNotesActivity.kt‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @author David Crespo Ríos
55
* @author Jorge Aguado Recio
66
*
7-
* Copyright (C) 2025 ownCloud GmbH.
7+
* Copyright (C) 2026 ownCloud GmbH.
88
*
99
* This program is free software: you can redistribute it and/or modify
1010
* it under the terms of the GNU General Public License version 2,
@@ -25,6 +25,8 @@ import android.content.Context
2525
import android.content.Intent
2626
import android.os.Bundle
2727
import androidx.appcompat.app.AppCompatActivity
28+
import androidx.core.view.ViewCompat
29+
import androidx.core.view.WindowInsetsCompat
2830
import androidx.recyclerview.widget.LinearLayoutManager
2931
import com.owncloud.android.BuildConfig
3032
import com.owncloud.android.MainApp
@@ -49,6 +51,7 @@ class ReleaseNotesActivity : AppCompatActivity() {
4951
super.onCreate(savedInstanceState)
5052
_binding = ReleaseNotesActivityBinding.inflate(layoutInflater)
5153
setContentView(binding.root)
54+
adaptInfiniteEdges()
5255
setData()
5356
initView()
5457
}
@@ -83,6 +86,14 @@ class ReleaseNotesActivity : AppCompatActivity() {
8386
binding.txtFooter.text = footer
8487
}
8588

89+
private fun adaptInfiniteEdges() {
90+
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
91+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
92+
binding.root.setPadding(systemInsets.left, systemInsets.top, systemInsets.right, systemInsets.bottom)
93+
insets
94+
}
95+
}
96+
8697
companion object {
8798
fun runIfNeeded(context: Context) {
8899
if (context is ReleaseNotesActivity) {

‎owncloudApp/src/main/java/com/owncloud/android/presentation/settings/SettingsActivity.kt‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
* @author Juan Carlos Garrote Gascón
55
* @author David Crespo Ríos
66
* @author Aitor Ballesteros Pavón
7+
* @author Jorge Aguado Recio
78
*
8-
* Copyright (C) 2024 ownCloud GmbH.
9+
* Copyright (C) 2026 ownCloud GmbH.
910
* <p>
1011
* This program is free software: you can redistribute it and/or modify
1112
* it under the terms of the GNU General Public License version 2,
@@ -25,11 +26,13 @@ package com.owncloud.android.presentation.settings
2526
import android.content.Intent
2627
import android.os.Bundle
2728
import android.view.MenuItem
29+
import android.view.View
2830
import androidx.appcompat.app.AppCompatActivity
2931
import androidx.appcompat.widget.Toolbar
3032
import androidx.constraintlayout.widget.ConstraintLayout
3133
import androidx.core.view.isVisible
3234
import com.owncloud.android.R
35+
import com.owncloud.android.extensions.adaptInfiniteEdges
3336
import com.owncloud.android.presentation.settings.advanced.SettingsAdvancedFragment
3437
import com.owncloud.android.presentation.settings.automaticuploads.SettingsPictureUploadsFragment
3538
import com.owncloud.android.presentation.settings.automaticuploads.SettingsVideoUploadsFragment
@@ -44,6 +47,9 @@ class SettingsActivity : AppCompatActivity() {
4447
super.onCreate(savedInstanceState)
4548
setContentView(R.layout.activity_settings)
4649

50+
val settingsRoot = findViewById<View>(R.id.settings_root)
51+
adaptInfiniteEdges(settingsRoot)
52+
4753
val toolbar = findViewById<Toolbar>(R.id.standard_toolbar).apply {
4854
isVisible = true
4955
}

‎owncloudApp/src/main/java/com/owncloud/android/presentation/settings/privacypolicy/PrivacyPolicyActivity.kt‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
* ownCloud Android client application
33
*
44
* @author Juan Carlos Garrote Gascón
5+
* @author Jorge Aguado Recio
56
*
6-
* Copyright (C) 2021 ownCloud GmbH.
7+
* Copyright (C) 2026 ownCloud GmbH.
78
* <p>
89
* This program is free software: you can redistribute it and/or modify
910
* it under the terms of the GNU General Public License version 2,
@@ -22,6 +23,7 @@ package com.owncloud.android.presentation.settings.privacypolicy
2223

2324
import android.os.Bundle
2425
import android.view.MenuItem
26+
import android.view.View
2527
import android.webkit.WebChromeClient
2628
import android.webkit.WebView
2729
import android.webkit.WebViewClient
@@ -32,6 +34,7 @@ import androidx.appcompat.widget.Toolbar
3234
import androidx.constraintlayout.widget.ConstraintLayout
3335
import androidx.core.view.isVisible
3436
import com.owncloud.android.R
37+
import com.owncloud.android.extensions.adaptInfiniteEdges
3538
import com.owncloud.android.extensions.showMessageInSnackbar
3639
import com.owncloud.android.utils.PreferenceUtils
3740

@@ -43,6 +46,9 @@ class PrivacyPolicyActivity : AppCompatActivity() {
4346
super.onCreate(savedInstanceState)
4447
setContentView(R.layout.activity_privacy_policy)
4548

49+
val privacyPolicyRoot = findViewById<View>(R.id.activityPrivacyPolicyLayout)
50+
adaptInfiniteEdges(privacyPolicyRoot)
51+
4652
val toolbar = findViewById<Toolbar>(R.id.standard_toolbar).apply {
4753
setTitle(R.string.actionbar_privacy_policy)
4854
isVisible = true

‎owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
* @author Christian Schabesberger
99
* @author Aitor Ballesteros Pavón
1010
* @author Juan Carlos Garrote Gascón
11+
* @author Jorge Aguado Recio
1112
*
12-
* Copyright (C) 2024 ownCloud GmbH.
13+
* Copyright (C) 2026 ownCloud GmbH.
1314
*
1415
* This program is free software: you can redistribute it and/or modify
1516
* it under the terms of the GNU General Public License version 2,
@@ -39,6 +40,7 @@ import com.owncloud.android.domain.files.model.OCFile
3940
import com.owncloud.android.domain.sharing.shares.model.OCShare
4041
import com.owncloud.android.domain.sharing.shares.model.ShareType
4142
import com.owncloud.android.domain.utils.Event.EventObserver
43+
import com.owncloud.android.extensions.adaptInfiniteEdges
4244
import com.owncloud.android.extensions.showErrorInSnackbar
4345
import com.owncloud.android.lib.resources.shares.RemoteShare
4446
import com.owncloud.android.presentation.common.UIResult
@@ -68,6 +70,9 @@ class ShareActivity : FileActivity(), ShareFragmentListener {
6870

6971
setContentView(R.layout.share_activity)
7072

73+
val shareRoot = findViewById<View>(R.id.share_activity_layout)
74+
adaptInfiniteEdges(shareRoot)
75+
7176
setupStandardToolbar(
7277
title = null,
7378
displayHomeAsUpEnabled = true,

‎owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/members/SpaceMembersActivity.kt‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.owncloud.android.domain.links.model.OCLink
3232
import com.owncloud.android.domain.roles.model.OCRole
3333
import com.owncloud.android.domain.spaces.model.OCSpace
3434
import com.owncloud.android.domain.spaces.model.SpaceMember
35+
import com.owncloud.android.extensions.adaptInfiniteEdges
3536
import com.owncloud.android.presentation.common.ShareSheetHelper
3637
import com.owncloud.android.presentation.spaces.links.AddPublicLinkFragment
3738
import com.owncloud.android.ui.activity.FileActivity
@@ -47,6 +48,8 @@ class SpaceMembersActivity: FileActivity(), SpaceMembersFragment.SpaceMemberFrag
4748
binding = MembersActivityBinding.inflate(layoutInflater)
4849
setContentView(binding.root)
4950

51+
adaptInfiniteEdges(binding.root)
52+
5053
setupStandardToolbar(title = null, displayHomeAsUpEnabled = true, homeButtonEnabled = true, displayShowTitleEnabled = true)
5154

5255
supportActionBar?.setHomeActionContentDescription(R.string.common_back)

‎owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* @author Aitor Ballesteros Pavon
1111
* @author Jorge Aguado Recio
1212
*
13-
* Copyright (C) 2024 ownCloud GmbH.
13+
* Copyright (C) 2026 ownCloud GmbH.
1414
*
1515
* This program is free software: you can redistribute it and/or modify
1616
* it under the terms of the GNU General Public License version 2,
@@ -48,8 +48,11 @@ import androidx.appcompat.content.res.AppCompatResources
4848
import androidx.appcompat.widget.AppCompatImageView
4949
import androidx.constraintlayout.widget.ConstraintLayout
5050
import androidx.core.view.GravityCompat
51+
import androidx.core.view.ViewCompat
52+
import androidx.core.view.WindowInsetsCompat
5153
import androidx.core.view.get
5254
import androidx.core.view.isVisible
55+
import androidx.core.view.updatePadding
5356
import androidx.drawerlayout.widget.DrawerLayout
5457
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
5558
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -106,6 +109,8 @@ abstract class DrawerActivity : ToolbarActivity() {
106109
getDrawerLayout()?.filterTouchesWhenObscured = PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(this)
107110
getNavView()?.filterTouchesWhenObscured = PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(this)
108111

112+
adaptInfiniteEdges()
113+
109114
// Set background header image, if any
110115
if (resources.getBoolean(R.bool.use_drawer_background_header)) {
111116
getDrawerHeaderBackground()?.setImageResource(R.drawable.drawer_header_background)
@@ -607,6 +612,18 @@ abstract class DrawerActivity : ToolbarActivity() {
607612
*/
608613
protected abstract fun restart()
609614

615+
private fun adaptInfiniteEdges() {
616+
val navView = findViewById<NavigationView>(R.id.nav_view)
617+
val footer = navView.findViewById<View>(R.id.nav_drawer_footer)
618+
619+
ViewCompat.setOnApplyWindowInsetsListener(navView) { _, insets ->
620+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
621+
navView.updatePadding(left = systemInsets.left)
622+
footer.updatePadding(bottom = systemInsets.bottom)
623+
insets
624+
}
625+
}
626+
610627
companion object {
611628
const val CENTRAL_URL = "https://central.owncloud.org/"
612629
const val GITHUB_URL = "https://github.com/owncloud/android/issues/new/choose"

‎owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ import android.widget.TextView
5252
import androidx.activity.result.contract.ActivityResultContracts
5353
import androidx.appcompat.app.AlertDialog
5454
import androidx.core.content.ContextCompat
55+
import androidx.core.view.ViewCompat
56+
import androidx.core.view.WindowInsetsCompat
5557
import androidx.core.view.isVisible
5658
import androidx.fragment.app.Fragment
5759
import androidx.localbroadcastmanager.content.LocalBroadcastManager
@@ -250,6 +252,9 @@ class FileDisplayActivity : FileActivity(),
250252
val view = binding.root
251253
setContentView(view)
252254

255+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { window.isNavigationBarContrastEnforced = false }
256+
adaptInfiniteEdges()
257+
253258
// setup toolbar
254259
setupRootToolbar(
255260
isSearchEnabled = true,
@@ -2072,6 +2077,22 @@ class FileDisplayActivity : FileActivity(),
20722077
super.onKeyUp(keyCode, event)
20732078
}
20742079

2080+
private fun adaptInfiniteEdges() {
2081+
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
2082+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
2083+
2084+
binding.navCoordinatorLayout.appBarLayout.setPadding(systemInsets.left, 0, systemInsets.right, 0)
2085+
2086+
val content = binding.navCoordinatorLayout.navMainContainer.listLayout
2087+
content.setPadding(systemInsets.left, content.paddingTop, systemInsets.right, 0)
2088+
2089+
val bottomNavView = binding.navCoordinatorLayout.bottomNavView
2090+
bottomNavView.setPadding(bottomNavView.paddingLeft, bottomNavView.paddingTop, bottomNavView.paddingRight, systemInsets.bottom)
2091+
2092+
insets
2093+
}
2094+
}
2095+
20752096
companion object {
20762097
private const val TAG_LIST_OF_FILES = "LIST_OF_FILES"
20772098
private const val TAG_LIST_OF_SPACES = "LIST_OF_SPACES"

‎owncloudApp/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* @author Aitor Ballesteros Pavón
99
* @author Jorge Aguado Recio
1010
*
11-
* Copyright (C) 2025 ownCloud GmbH.
11+
* Copyright (C) 2026 ownCloud GmbH.
1212
*
1313
* This program is free software: you can redistribute it and/or modify
1414
* it under the terms of the GNU General Public License version 2,
@@ -37,6 +37,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager
3737
import com.owncloud.android.domain.files.model.FileListOption
3838
import com.owncloud.android.domain.files.model.OCFile
3939
import com.owncloud.android.domain.spaces.model.OCSpace
40+
import com.owncloud.android.extensions.adaptInfiniteEdges
4041
import com.owncloud.android.presentation.authentication.AccountUtils
4142
import com.owncloud.android.presentation.files.filelist.MainFileListFragment
4243
import com.owncloud.android.presentation.spaces.SpacesListFragment
@@ -65,6 +66,8 @@ open class FolderPickerActivity : FileActivity(),
6566
binding = FilesFolderPickerBinding.inflate(layoutInflater)
6667
setContentView(binding.root)
6768

69+
adaptInfiniteEdges(binding.root)
70+
6871
// Allow or disallow touches with other visible windows
6972
binding.filesFolderPickerLayout.filterTouchesWhenObscured = PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(this)
7073

0 commit comments

Comments
 (0)