@@ -26,11 +26,13 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener
26
26
import android.view.animation.DecelerateInterpolator
27
27
import android.widget.ImageView
28
28
import android.widget.LinearLayout
29
+ import androidx.core.animation.addListener
29
30
import androidx.core.view.isVisible
30
31
import androidx.core.view.marginBottom
31
32
import androidx.core.view.marginEnd
32
33
import androidx.core.view.marginStart
33
34
import androidx.core.view.marginTop
35
+ import androidx.core.view.updateLayoutParams
34
36
import androidx.core.view.updatePadding
35
37
import com.duckduckgo.anvil.annotations.InjectWith
36
38
import com.duckduckgo.app.browser.R
@@ -45,6 +47,7 @@ import com.duckduckgo.app.browser.omnibar.model.OmnibarPosition
45
47
import com.duckduckgo.common.ui.view.gone
46
48
import com.duckduckgo.common.ui.view.hide
47
49
import com.duckduckgo.common.ui.view.show
50
+ import com.duckduckgo.common.ui.view.toDp
48
51
import com.duckduckgo.di.scopes.FragmentScope
49
52
import com.duckduckgo.mobile.android.R as CommonR
50
53
import com.google.android.material.card.MaterialCardView
@@ -98,17 +101,6 @@ class FadeOmnibarLayout @JvmOverloads constructor(
98
101
}
99
102
private val omnibarCardFocusedMarginTop by lazy { resources.getDimensionPixelSize(CommonR .dimen.experimentalOmnibarCardFocusedMarginTop) }
100
103
private val omnibarCardFocusedMarginBottom by lazy { resources.getDimensionPixelSize(CommonR .dimen.experimentalOmnibarCardFocusedMarginBottom) }
101
- private val omnibarContentPadding by lazy { resources.getDimensionPixelSize(CommonR .dimen.experimentalOmnibarContentPadding) }
102
- private val omnibarContentFocusedPaddingHorizontal by lazy {
103
- resources.getDimensionPixelSize(
104
- CommonR .dimen.experimentalOmnibarContentFocusedPaddingHorizontal,
105
- )
106
- }
107
- private val omnibarContentFocusedPaddingVertical by lazy {
108
- resources.getDimensionPixelSize(
109
- CommonR .dimen.experimentalOmnibarContentFocusedPaddingVertical,
110
- )
111
- }
112
104
private val omnibarOutlineWidth by lazy { resources.getDimensionPixelSize(CommonR .dimen.experimentalOmnibarOutlineWidth) }
113
105
private val omnibarOutlineFocusedWidth by lazy { resources.getDimensionPixelSize(CommonR .dimen.experimentalOmnibarOutlineFocusedWidth) }
114
106
@@ -127,18 +119,21 @@ class FadeOmnibarLayout @JvmOverloads constructor(
127
119
val navBar = rootContainer.findViewById<BrowserNavigationBarView >(R .id.omnibarNavigationBar)
128
120
if (omnibarPosition == OmnibarPosition .TOP ) {
129
121
rootContainer.removeView(navBar)
122
+
123
+ omnibarCard.elevation = 1f .toDp(context)
130
124
} else {
131
125
navigationBar = navBar
132
126
133
127
// When omnibar is at the bottom, we're adding an additional space at the top
134
128
toolbarContainer.updatePadding(
135
129
top = toolbarContainerPaddingTopWhenAtBottom,
136
130
)
137
-
138
131
// at the same time, we remove that space from the navigation bar which now sits below the omnibar
139
132
navBar.findViewById<LinearLayout >(R .id.rootView).updatePadding(
140
133
top = 0 ,
141
134
)
135
+
136
+ omnibarCard.elevation = 0.5f .toDp(context)
142
137
}
143
138
}
144
139
@@ -153,6 +148,19 @@ class FadeOmnibarLayout @JvmOverloads constructor(
153
148
findInPage.findInPageContainer.viewTreeObserver.removeOnGlobalLayoutListener(findInPageLayoutVisibilityChangeListener)
154
149
}
155
150
151
+ override fun onSizeChanged (
152
+ w : Int ,
153
+ h : Int ,
154
+ oldw : Int ,
155
+ oldh : Int ,
156
+ ) {
157
+ super .onSizeChanged(w, h, oldw, oldh)
158
+ if (w != oldw || h != oldh) {
159
+ // This allows the view to adjust to configuration changes, even if it's currently in the focused state.
160
+ unlockContentDimensions()
161
+ }
162
+ }
163
+
156
164
override fun render (viewState : ViewState ) {
157
165
super .render(viewState)
158
166
outlineProvider = if (viewState.viewMode is ViewMode .CustomTab ) {
@@ -216,41 +224,25 @@ class FadeOmnibarLayout @JvmOverloads constructor(
216
224
val startCardMarginBottom = omnibarCard.marginBottom
217
225
val startCardMarginStart = omnibarCard.marginStart
218
226
val startCardMarginEnd = omnibarCard.marginEnd
219
- val startContentPaddingTop = omnibarCard.contentPaddingTop
220
- val startContentPaddingBottom = omnibarCard.contentPaddingBottom
221
- val startContentPaddingStart = omnibarCard.contentPaddingLeft
222
- val startContentPaddingEnd = omnibarCard.contentPaddingRight
223
227
val startCardStrokeWidth = omnibarCard.strokeWidth
224
228
225
229
val endCardMarginTop: Int
226
230
val endCardMarginBottom: Int
227
231
val endCardMarginStart: Int
228
232
val endCardMarginEnd: Int
229
- val endContentPaddingTop: Int
230
- val endContentPaddingBottom: Int
231
- val endContentPaddingStart: Int
232
- val endContentPaddingEnd: Int
233
233
val endCardStrokeWidth: Int
234
234
235
235
if (focused) {
236
236
endCardMarginTop = omnibarCardFocusedMarginTop
237
237
endCardMarginBottom = omnibarCardFocusedMarginBottom
238
238
endCardMarginStart = omnibarCardFocusedMarginHorizontal
239
239
endCardMarginEnd = omnibarCardFocusedMarginHorizontal
240
- endContentPaddingTop = omnibarContentFocusedPaddingVertical
241
- endContentPaddingBottom = omnibarContentFocusedPaddingVertical
242
- endContentPaddingStart = omnibarContentFocusedPaddingHorizontal
243
- endContentPaddingEnd = omnibarContentFocusedPaddingHorizontal
244
240
endCardStrokeWidth = omnibarOutlineFocusedWidth
245
241
} else {
246
242
endCardMarginTop = omnibarCardMarginTop
247
243
endCardMarginBottom = omnibarCardMarginBottom
248
244
endCardMarginStart = omnibarCardMarginHorizontal
249
245
endCardMarginEnd = omnibarCardMarginHorizontal
250
- endContentPaddingTop = omnibarContentPadding
251
- endContentPaddingBottom = omnibarContentPadding
252
- endContentPaddingStart = omnibarContentPadding
253
- endContentPaddingEnd = omnibarContentPadding
254
246
endCardStrokeWidth = omnibarOutlineWidth
255
247
}
256
248
@@ -264,10 +256,6 @@ class FadeOmnibarLayout @JvmOverloads constructor(
264
256
val animatedCardMarginBottom = (startCardMarginBottom + (endCardMarginBottom - startCardMarginBottom) * fraction).toInt()
265
257
val animatedCardMarginStart = (startCardMarginStart + (endCardMarginStart - startCardMarginStart) * fraction).toInt()
266
258
val animatedCardMarginEnd = (startCardMarginEnd + (endCardMarginEnd - startCardMarginEnd) * fraction).toInt()
267
- val animatedContentPaddingTop = (startContentPaddingTop + (endContentPaddingTop - startContentPaddingTop) * fraction).toInt()
268
- val animatedContentPaddingBottom = (startContentPaddingBottom + (endContentPaddingBottom - startContentPaddingBottom) * fraction).toInt()
269
- val animatedContentPaddingStart = (startContentPaddingStart + (endContentPaddingStart - startContentPaddingStart) * fraction).toInt()
270
- val animatedContentPaddingEnd = (startContentPaddingEnd + (endContentPaddingEnd - startContentPaddingEnd) * fraction).toInt()
271
259
val animatedCardStrokeWidth = (startCardStrokeWidth + (endCardStrokeWidth - startCardStrokeWidth) * fraction).toInt()
272
260
273
261
val params = omnibarCard.layoutParams as MarginLayoutParams
@@ -277,20 +265,54 @@ class FadeOmnibarLayout @JvmOverloads constructor(
277
265
params.bottomMargin = animatedCardMarginBottom
278
266
omnibarCard.setLayoutParams(params)
279
267
280
- omnibarCard.setContentPadding(
281
- animatedContentPaddingStart,
282
- animatedContentPaddingTop,
283
- animatedContentPaddingEnd,
284
- animatedContentPaddingBottom,
285
- )
286
-
287
268
omnibarCard.strokeWidth = animatedCardStrokeWidth
288
269
}
289
270
271
+ animator.addListener(
272
+ onStart = {
273
+ lockContentDimensions()
274
+ },
275
+ onEnd = {
276
+ // Only unlock content size when we're back to unfocused state.
277
+ if (! focused) {
278
+ unlockContentDimensions()
279
+ }
280
+ },
281
+ onCancel = {
282
+ // Ensuring that onEnd, and consequently #unlockContentDimensions(), is not called when transition is canceled,
283
+ // which can result in content jumping to match_parent while the transition is not finished yet.
284
+ // We only want to unlock when we're fully transitioned back to unfocused state.
285
+ animator.removeAllListeners()
286
+ },
287
+ )
288
+
290
289
animator.start()
291
290
focusAnimator = animator
292
291
}
293
292
293
+ /* *
294
+ * Lock content dimensions so that the view doesn't respond to the wrapping card's size changes.
295
+ *
296
+ * When focused, we resize the wrapping card to make the stroke appear "outside" but we don't want the content to expand with it.
297
+ */
298
+ private fun lockContentDimensions () {
299
+ omniBarContentContainer.updateLayoutParams {
300
+ width = omniBarContentContainer.measuredWidth
301
+ height = omniBarContentContainer.measuredHeight
302
+ }
303
+ }
304
+
305
+ /* *
306
+ * Unlock content dimensions so that the view can correctly respond to changes in the viewport size,
307
+ * like resizing the app window or changing device orientation.
308
+ */
309
+ private fun unlockContentDimensions () {
310
+ omniBarContentContainer.updateLayoutParams {
311
+ width = ViewGroup .LayoutParams .MATCH_PARENT
312
+ height = ViewGroup .LayoutParams .MATCH_PARENT
313
+ }
314
+ }
315
+
294
316
private fun onFindInPageShown () {
295
317
omniBarContentContainer.gone()
296
318
customTabToolbarContainerWrapper.gone()
0 commit comments