Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 12d9fa8

Browse files
committed
Update handling of window insets across the app
Change-Id: Ia5af3006cd28c40597180ac3b5298df3ffb2cd4c
1 parent 3168441 commit 12d9fa8

File tree

18 files changed

+153
-62
lines changed

18 files changed

+153
-62
lines changed

mobile/src/main/java/com/google/samples/apps/iosched/ui/MainActivity.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ import android.view.Menu
2424
import androidx.activity.viewModels
2525
import androidx.appcompat.app.AppCompatActivity
2626
import androidx.appcompat.widget.Toolbar
27+
import androidx.core.graphics.Insets
28+
import androidx.core.view.ViewCompat
29+
import androidx.core.view.WindowCompat
30+
import androidx.core.view.WindowInsetsCompat
31+
import androidx.core.view.isVisible
32+
import androidx.core.view.updatePadding
2733
import androidx.lifecycle.Lifecycle
2834
import androidx.lifecycle.lifecycleScope
2935
import androidx.lifecycle.repeatOnLifecycle
@@ -115,6 +121,7 @@ class MainActivity : AppCompatActivity(), NavigationHost {
115121

116122
// Update for Dark Mode straight away
117123
updateForTheme(viewModel.currentTheme)
124+
WindowCompat.setDecorFitsSystemWindows(window, false)
118125

119126
binding = ActivityMainBinding.inflate(layoutInflater)
120127
setContentView(binding.root)
@@ -178,6 +185,37 @@ class MainActivity : AppCompatActivity(), NavigationHost {
178185
}
179186
}
180187
}
188+
189+
binding.navigationRail?.let {
190+
ViewCompat.setOnApplyWindowInsetsListener(it) { view, insets ->
191+
// Pad the Navigation Rail so its content is not behind system bars.
192+
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
193+
view.updatePadding(top = systemBars.top, bottom = systemBars.bottom)
194+
insets
195+
}
196+
}
197+
ViewCompat.setOnApplyWindowInsetsListener(binding.rootContainer) { view, insets ->
198+
// Hide the bottom navigation view whenever the keyboard is visible.
199+
val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
200+
binding.bottomNavigation?.isVisible = !imeVisible
201+
202+
// If we're showing the bottom navigation, add bottom padding. Also, add left and right
203+
// padding since there's no better we can do with horizontal insets.
204+
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
205+
val bottomPadding = if (binding.bottomNavigation?.isVisible == true) {
206+
systemBars.bottom
207+
} else 0
208+
view.updatePadding(
209+
left = systemBars.left,
210+
right = systemBars.right,
211+
bottom = bottomPadding
212+
)
213+
// Consume the insets we've used.
214+
WindowInsetsCompat.Builder(insets).setInsets(
215+
WindowInsetsCompat.Type.systemBars(),
216+
Insets.of(0, systemBars.top, 0, systemBars.bottom - bottomPadding)
217+
).build()
218+
}
181219
}
182220

183221
private fun configureNavMenu(menu: Menu) {

mobile/src/main/java/com/google/samples/apps/iosched/ui/agenda/AgendaFragment.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
2323
import androidx.core.view.WindowInsetsCompat
24-
import androidx.core.view.updatePaddingRelative
24+
import androidx.core.view.updatePadding
2525
import androidx.databinding.BindingAdapter
2626
import androidx.fragment.app.activityViewModels
2727
import androidx.fragment.app.viewModels
@@ -54,10 +54,10 @@ class AgendaFragment : MainNavigationFragment() {
5454
}
5555
// Pad the bottom of the RecyclerView so that the content scrolls up above the nav bar
5656
binding.recyclerView.doOnApplyWindowInsets { v, insets, padding ->
57-
v.updatePaddingRelative(
58-
bottom =
59-
padding.bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom
57+
val systemInsets = insets.getInsets(
58+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
6059
)
60+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
6161
}
6262
return binding.root
6363
}

mobile/src/main/java/com/google/samples/apps/iosched/ui/codelabs/CodelabsFragment.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.os.Bundle
2121
import android.view.LayoutInflater
2222
import android.view.View
2323
import android.view.ViewGroup
24+
import androidx.core.view.WindowInsetsCompat
2425
import androidx.core.view.updatePadding
2526
import androidx.fragment.app.activityViewModels
2627
import androidx.fragment.app.viewModels
@@ -92,7 +93,10 @@ class CodelabsFragment : MainNavigationFragment(), CodelabsActionsHandler {
9293

9394
// Pad the bottom of the RecyclerView so that the content scrolls up above the nav bar
9495
binding.codelabsList.doOnApplyWindowInsets { v, insets, padding ->
95-
v.updatePadding(bottom = padding.bottom + insets.systemWindowInsetBottom)
96+
val systemInsets = insets.getInsets(
97+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
98+
)
99+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
96100
}
97101

98102
launchAndRepeatWithViewLifecycle {

mobile/src/main/java/com/google/samples/apps/iosched/ui/feed/AnnouncementsFragment.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ import android.os.Bundle
2020
import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
23+
import androidx.core.view.WindowInsetsCompat
2324
import androidx.core.view.isVisible
24-
import androidx.core.view.updatePaddingRelative
25+
import androidx.core.view.updatePadding
2526
import androidx.fragment.app.activityViewModels
2627
import androidx.fragment.app.viewModels
2728
import androidx.lifecycle.Observer
@@ -69,15 +70,19 @@ class AnnouncementsFragment : MainNavigationFragment() {
6970
binding.toolbar.setupProfileMenuItem(mainActivityViewModel, viewLifecycleOwner)
7071

7172
binding.root.doOnApplyWindowInsets { _, insets, _ ->
73+
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
7274
binding.statusBar.run {
73-
layoutParams.height = insets.systemWindowInsetTop
75+
layoutParams.height = systemInsets.top
7476
isVisible = layoutParams.height > 0
7577
requestLayout()
7678
}
7779
}
7880

7981
binding.recyclerView.doOnApplyWindowInsets { v, insets, padding ->
80-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
82+
val systemInsets = insets.getInsets(
83+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
84+
)
85+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
8186
}
8287

8388
model.announcements.observe(

mobile/src/main/java/com/google/samples/apps/iosched/ui/feed/FeedFragment.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ import android.os.Bundle
2020
import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
23+
import androidx.core.view.WindowInsetsCompat
2324
import androidx.core.view.doOnLayout
2425
import androidx.core.view.isVisible
25-
import androidx.core.view.updatePaddingRelative
26+
import androidx.core.view.updatePadding
2627
import androidx.fragment.app.activityViewModels
2728
import androidx.fragment.app.viewModels
2829
import androidx.navigation.fragment.findNavController
@@ -102,8 +103,9 @@ class FeedFragment : MainNavigationFragment() {
102103
binding.toolbar.setupProfileMenuItem(mainActivityViewModel, viewLifecycleOwner)
103104

104105
binding.root.doOnApplyWindowInsets { _, insets, _ ->
106+
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
105107
binding.statusBar.run {
106-
layoutParams.height = insets.systemWindowInsetTop
108+
layoutParams.height = systemBars.top
107109
isVisible = layoutParams.height > 0
108110
requestLayout()
109111
}
@@ -121,11 +123,17 @@ class FeedFragment : MainNavigationFragment() {
121123
}
122124

123125
binding.recyclerView.doOnApplyWindowInsets { v, insets, padding ->
124-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
126+
val systemInsets = insets.getInsets(
127+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
128+
)
129+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
125130
}
126131

127132
binding.snackbar.doOnApplyWindowInsets { v, insets, padding ->
128-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
133+
val systemInsets = insets.getInsets(
134+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
135+
)
136+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
129137
}
130138

131139
setupSnackbarManager(snackbarMessageManager, binding.snackbar)

mobile/src/main/java/com/google/samples/apps/iosched/ui/filters/FiltersFragment.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ import android.view.View
2222
import android.view.ViewGroup
2323
import android.view.ViewGroup.MarginLayoutParams
2424
import androidx.activity.OnBackPressedCallback
25+
import androidx.core.view.WindowInsetsCompat
2526
import androidx.core.view.doOnLayout
2627
import androidx.core.view.marginBottom
2728
import androidx.core.view.updateLayoutParams
28-
import androidx.core.view.updatePaddingRelative
29+
import androidx.core.view.updatePadding
2930
import androidx.databinding.ObservableFloat
3031
import androidx.fragment.app.Fragment
3132
import androidx.recyclerview.widget.RecyclerView
@@ -99,7 +100,10 @@ abstract class FiltersFragment : Fragment() {
99100

100101
// Pad the bottom of the RecyclerView so that the content scrolls up above the nav bar
101102
binding.recyclerviewFilters.doOnApplyWindowInsets { v, insets, padding ->
102-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
103+
val systemInsets = insets.getInsets(
104+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
105+
)
106+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
103107
}
104108

105109
return binding.root
@@ -137,12 +141,12 @@ abstract class FiltersFragment : Fragment() {
137141
val peekHeight = behavior.peekHeight
138142
val marginBottom = binding.root.marginBottom
139143
binding.root.doOnApplyWindowInsets { v, insets, _ ->
140-
val gestureInsets = insets.systemGestureInsets
144+
val gestureInsets = insets.getInsets(WindowInsetsCompat.Type.systemGestures())
141145
// Update the peek height so that it is above the navigation bar
142146
behavior.peekHeight = gestureInsets.bottom + peekHeight
143147

144148
v.updateLayoutParams<MarginLayoutParams> {
145-
bottomMargin = marginBottom + insets.systemWindowInsetTop
149+
bottomMargin = marginBottom + gestureInsets.top
146150
}
147151
}
148152

mobile/src/main/java/com/google/samples/apps/iosched/ui/info/EventFragment.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import android.view.View.GONE
2525
import android.view.View.VISIBLE
2626
import android.view.ViewGroup
2727
import android.widget.TextView
28-
import androidx.core.view.updatePaddingRelative
28+
import androidx.core.view.WindowInsetsCompat
29+
import androidx.core.view.updatePadding
2930
import androidx.databinding.BindingAdapter
3031
import androidx.fragment.app.Fragment
3132
import androidx.fragment.app.viewModels
@@ -70,7 +71,10 @@ class EventFragment : Fragment() {
7071

7172
// Pad the bottom of the content so that it is above the nav bar
7273
binding.content.doOnApplyWindowInsets { v, insets, padding ->
73-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
74+
val systemInsets = insets.getInsets(
75+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
76+
)
77+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
7478
}
7579

7680
val snackbarLayout = requireActivity().findViewById<FadingSnackbar>(R.id.snackbar)

mobile/src/main/java/com/google/samples/apps/iosched/ui/info/FaqFragment.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import android.os.Bundle
2020
import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
23-
import androidx.core.view.updatePaddingRelative
23+
import androidx.core.view.WindowInsetsCompat
24+
import androidx.core.view.updatePadding
2425
import androidx.fragment.app.Fragment
2526
import com.google.samples.apps.iosched.R
2627
import com.google.samples.apps.iosched.util.doOnApplyWindowInsets
@@ -40,9 +41,12 @@ class FaqFragment : Fragment() {
4041
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
4142
super.onViewCreated(view, savedInstanceState)
4243

43-
// Pad the bottom of the ScrollView so that it scrolls up above the nav bar
44+
// Pad the bottom of the ScrollView so that the content scrolls up past any system bars.
4445
view.doOnApplyWindowInsets { v, insets, padding ->
45-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
46+
val systemInsets = insets.getInsets(
47+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
48+
)
49+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
4650
}
4751
}
4852
}

mobile/src/main/java/com/google/samples/apps/iosched/ui/info/InfoFragment.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import android.os.Bundle
2020
import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
23-
import androidx.core.view.updatePaddingRelative
23+
import androidx.core.view.WindowInsetsCompat
24+
import androidx.core.view.updatePadding
2425
import androidx.fragment.app.Fragment
2526
import androidx.fragment.app.viewModels
2627
import androidx.viewpager2.adapter.FragmentStateAdapter
@@ -54,7 +55,10 @@ class InfoFragment : MainNavigationFragment() {
5455
lifecycleOwner = viewLifecycleOwner
5556
}
5657
binding.viewpager.doOnApplyWindowInsets { v, insets, padding ->
57-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
58+
val systemInsets = insets.getInsets(
59+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
60+
)
61+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
5862
}
5963
return binding.root
6064
}

mobile/src/main/java/com/google/samples/apps/iosched/ui/info/TravelFragment.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import android.os.Bundle
2020
import android.view.LayoutInflater
2121
import android.view.View
2222
import android.view.ViewGroup
23-
import androidx.core.view.updatePaddingRelative
23+
import androidx.core.view.WindowInsetsCompat
24+
import androidx.core.view.updatePadding
2425
import androidx.fragment.app.Fragment
2526
import com.google.samples.apps.iosched.R
2627
import com.google.samples.apps.iosched.util.doOnApplyWindowInsets
@@ -42,7 +43,10 @@ class TravelFragment : Fragment() {
4243

4344
// Pad the bottom of the ScrollView so that it scrolls up above the nav bar
4445
view.doOnApplyWindowInsets { v, insets, padding ->
45-
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
46+
val systemInsets = insets.getInsets(
47+
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
48+
)
49+
v.updatePadding(bottom = padding.bottom + systemInsets.bottom)
4650
}
4751
}
4852
}

0 commit comments

Comments
 (0)