Skip to content

Commit 532508d

Browse files
committed
use colored backdrop for Input Screen alpha transitions on API 33+
1 parent 0f31f65 commit 532508d

File tree

13 files changed

+135
-109
lines changed

13 files changed

+135
-109
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ import com.duckduckgo.browser.api.ui.BrowserScreens.PrivateSearchScreenNoParams
246246
import com.duckduckgo.browser.api.ui.BrowserScreens.WebViewActivityWithParams
247247
import com.duckduckgo.common.ui.DuckDuckGoActivity
248248
import com.duckduckgo.common.ui.DuckDuckGoFragment
249-
import com.duckduckgo.common.ui.anim.AnimationResourceProvider
250249
import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore
251250
import com.duckduckgo.common.ui.store.BrowserAppTheme
252251
import com.duckduckgo.common.ui.tabs.SwipingTabsFeatureProvider
@@ -288,6 +287,7 @@ import com.duckduckgo.downloads.api.DownloadsFileActions
288287
import com.duckduckgo.downloads.api.FileDownloader
289288
import com.duckduckgo.downloads.api.FileDownloader.PendingFileDownload
290289
import com.duckduckgo.duckchat.api.DuckChat
290+
import com.duckduckgo.duckchat.api.InputScreenAnimationResourceProvider
291291
import com.duckduckgo.duckchat.impl.inputscreen.ui.InputScreenActivity.Companion.QUERY
292292
import com.duckduckgo.duckchat.impl.inputscreen.ui.InputScreenActivity.Companion.TAB_ID
293293
import com.duckduckgo.duckchat.impl.inputscreen.ui.InputScreenActivityParams
@@ -1075,8 +1075,8 @@ class BrowserTabFragment :
10751075
requireContext(),
10761076
InputScreenActivityParams(query = query),
10771077
)
1078-
val enterTransition = AnimationResourceProvider.getSlideInFromTopFadeIn()
1079-
val exitTransition = AnimationResourceProvider.getSlideOutToBottomFadeOut()
1078+
val enterTransition = InputScreenAnimationResourceProvider.getInputScreenEnterAnimation()
1079+
val exitTransition = InputScreenAnimationResourceProvider.getBrowserExitAnimation(appTheme.isLightModeEnabled())
10801080
val options = ActivityOptionsCompat.makeCustomAnimation(
10811081
requireActivity(),
10821082
enterTransition,

common/common-ui/src/main/java/com/duckduckgo/common/ui/anim/AnimationResourceProvider.kt

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.duckchat.api
18+
19+
import android.os.Build.VERSION
20+
21+
/**
22+
* Provides animation resources for activity transitions between input screens and browser.
23+
*
24+
* ### API Level Behavior
25+
* - **API < 33**: Uses simple fade animations as slide animations don't seem to be supported (on tested devices).
26+
* - **API ≥ 33**: Uses slide animations with fade effects.
27+
*
28+
* ### Backdrop Color Handling
29+
* Alpha transitions on activities fade the entire window, revealing the black system background.
30+
* To prevent this visual artifact (especially noticeable in light mode), browser animations use
31+
* a backdrop color that matches the activity background.
32+
* Only one animation component needs backdrop color to prevent system background from showing through,
33+
* so we're only applying it to browser animations.
34+
*
35+
* **Limitations:**
36+
* - Backdrop color API is only available from API 33+, so black still shows through on lower APIs,
37+
* but it's less dramatic because there's no slide animation.
38+
* - Cannot use themeable attributes (`?attr`) as they cause crashes of the whole launcher (on tested devices).
39+
* Instead, we use fixed color values and filter resources by current theme state.
40+
*/
41+
object InputScreenAnimationResourceProvider {
42+
43+
fun getBrowserEnterAnimation(isLightModeEnabled: Boolean): Int {
44+
return if (VERSION.SDK_INT >= 33) {
45+
if (isLightModeEnabled) {
46+
R.anim.slide_in_from_bottom_fade_in_light
47+
} else {
48+
R.anim.slide_in_from_bottom_fade_in_dark
49+
}
50+
} else {
51+
R.anim.fade_in
52+
}
53+
}
54+
55+
fun getInputScreenExitAnimation(): Int {
56+
return if (VERSION.SDK_INT >= 33) {
57+
R.anim.slide_out_to_top_fade_out
58+
} else {
59+
R.anim.fade_out
60+
}
61+
}
62+
63+
fun getInputScreenEnterAnimation(): Int {
64+
return if (VERSION.SDK_INT >= 33) {
65+
R.anim.slide_in_from_top_fade_in
66+
} else {
67+
R.anim.fade_in
68+
}
69+
}
70+
71+
fun getBrowserExitAnimation(isLightModeEnabled: Boolean): Int {
72+
return if (VERSION.SDK_INT >= 33) {
73+
if (isLightModeEnabled) {
74+
R.anim.slide_out_to_bottom_fade_out_light
75+
} else {
76+
R.anim.slide_out_to_bottom_fade_out_dark
77+
}
78+
} else {
79+
R.anim.fade_out
80+
}
81+
}
82+
}

common/common-ui/src/main/res/anim/slide_in_from_bottom_fade_in_overshoot.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_in_from_bottom_fade_in_dark.xml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,18 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@anim/overshoot_interpolator_tension_1">
18+
android:backdropColor="@color/background_background_dark"
19+
android:duration="@integer/slide_animation_duration_ms"
20+
android:showBackdrop="true">
2121

2222
<translate
2323
android:fromYDelta="56dp"
24+
android:interpolator="@anim/overshoot_interpolator_tension_1"
2425
android:toYDelta="0dp" />
2526

2627
<alpha
2728
android:fromAlpha="0.0"
29+
android:interpolator="@android:anim/decelerate_interpolator"
2830
android:toAlpha="1.0" />
2931

3032
</set>

common/common-ui/src/main/res/anim/slide_in_from_top_fade_in_overshoot.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_in_from_bottom_fade_in_light.xml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,18 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@anim/overshoot_interpolator_tension_1">
18+
android:backdropColor="@color/background_background_light"
19+
android:duration="@integer/slide_animation_duration_ms"
20+
android:showBackdrop="true">
2121

2222
<translate
23-
android:fromYDelta="-56dp"
23+
android:fromYDelta="56dp"
24+
android:interpolator="@anim/overshoot_interpolator_tension_1"
2425
android:toYDelta="0dp" />
2526

2627
<alpha
2728
android:fromAlpha="0.0"
29+
android:interpolator="@android:anim/decelerate_interpolator"
2830
android:toAlpha="1.0" />
2931

3032
</set>

common/common-ui/src/main/res/anim/slide_in_from_top_fade_in.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_in_from_top_fade_in.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,16 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@android:anim/decelerate_interpolator">
18+
android:duration="@integer/slide_animation_duration_ms">
2119

2220
<translate
2321
android:fromYDelta="-56dp"
22+
android:interpolator="@anim/overshoot_interpolator_tension_1"
2423
android:toYDelta="0dp" />
2524

2625
<alpha
2726
android:fromAlpha="0.0"
27+
android:interpolator="@android:anim/decelerate_interpolator"
2828
android:toAlpha="1.0" />
2929

3030
</set>

common/common-ui/src/main/res/anim/slide_out_to_bottom_fade_out_overshoot.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_out_to_bottom_fade_out_dark.xml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,18 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@anim/overshoot_interpolator_tension_1">
18+
android:backdropColor="@color/background_background_dark"
19+
android:duration="@integer/slide_animation_duration_ms"
20+
android:showBackdrop="true">
2121

2222
<translate
2323
android:fromYDelta="0dp"
24+
android:interpolator="@anim/overshoot_interpolator_tension_1"
2425
android:toYDelta="56dp" />
2526

2627
<alpha
2728
android:fromAlpha="1.0"
29+
android:interpolator="@android:anim/decelerate_interpolator"
2830
android:toAlpha="0.0" />
2931

3032
</set>

common/common-ui/src/main/res/anim/slide_out_to_top_fade_out_overshoot.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_out_to_bottom_fade_out_light.xml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,18 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@anim/overshoot_interpolator_tension_1">
18+
android:backdropColor="@color/background_background_light"
19+
android:duration="@integer/slide_animation_duration_ms"
20+
android:showBackdrop="true">
2121

2222
<translate
2323
android:fromYDelta="0dp"
24-
android:toYDelta="-56dp" />
24+
android:interpolator="@anim/overshoot_interpolator_tension_1"
25+
android:toYDelta="56dp" />
2526

2627
<alpha
2728
android:fromAlpha="1.0"
29+
android:interpolator="@android:anim/decelerate_interpolator"
2830
android:toAlpha="0.0" />
2931

3032
</set>

common/common-ui/src/main/res/anim/slide_out_to_top_fade_out.xml renamed to duckchat/duckchat-api/src/main/res/anim-v33/slide_out_to_top_fade_out.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,16 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@android:anim/decelerate_interpolator">
18+
android:duration="@integer/slide_animation_duration_ms">
2119

2220
<translate
2321
android:fromYDelta="0dp"
22+
android:interpolator="@anim/overshoot_interpolator_tension_1"
2423
android:toYDelta="-56dp" />
2524

2625
<alpha
2726
android:fromAlpha="1.0"
27+
android:interpolator="@android:anim/decelerate_interpolator"
2828
android:toAlpha="0.0" />
2929

3030
</set>

common/common-ui/src/main/res/anim/slide_in_from_bottom_fade_in.xml renamed to duckchat/duckchat-api/src/main/res/anim/fade_in.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ Copyright (c) 2025 DuckDuckGo
43
~
54
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,15 +15,11 @@
1615
-->
1716

1817
<set xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:duration="300"
20-
android:interpolator="@android:anim/decelerate_interpolator">
21-
22-
<translate
23-
android:fromYDelta="56dp"
24-
android:toYDelta="0dp" />
18+
android:duration="@integer/slide_animation_duration_ms">
2519

2620
<alpha
2721
android:fromAlpha="0.0"
22+
android:interpolator="@android:anim/decelerate_interpolator"
2823
android:toAlpha="1.0" />
2924

3025
</set>

0 commit comments

Comments
 (0)