Adapt FinishActivity and outro for 14 QPR3
windowShowWallpaper behaves unexpectedly with transitions as of 14 QPR3.
As a result, the changes of "Revamp outro animation" were causing the
transition into the final page of the wizard to instantaneously have
a transparent wallpaper background, even before the animation finished.
This was jarring and odd, so now we use a regular theme until we are
ready to start our animation, at which point we recreate the activity
with the EdgeToEdgeWallpaperBackground (windowShowWallpaper) theme
before running the animation.
Change-Id: Ib19918d7d2a615aff44a48066b17ec9d2f04bac6
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 30d5357..f9fdd4a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -284,7 +284,6 @@
<activity
android:name=".FinishActivity"
- android:theme="@style/EdgeToEdgeWallpaperBackground"
android:label="@string/activity_label_empty"
android:configChanges="mcc|mnc"
android:immersive="true"
diff --git a/src/org/lineageos/setupwizard/FinishActivity.java b/src/org/lineageos/setupwizard/FinishActivity.java
index 71e61ba..96a8de8 100644
--- a/src/org/lineageos/setupwizard/FinishActivity.java
+++ b/src/org/lineageos/setupwizard/FinishActivity.java
@@ -10,7 +10,9 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -32,7 +34,13 @@
private final Handler mHandler = new Handler(Looper.getMainLooper());
- private boolean mIsFinishing;
+ // "Why not just start this activity with an Intent extra?" you might ask. Been there.
+ // We need this to affect the theme, and even onCreate is not early enough for that,
+ // so "static volatile boolean" it is. Feel free to rework this if you dare.
+ private static volatile boolean sIsFinishing;
+
+ private View mRootView;
+ private Resources.Theme mEdgeToEdgeWallpaperBackgroundTheme;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -52,8 +60,8 @@
window.setNavigationBarContrastEnforced(false);
// Ensure the main layout (not including the background view) does not get obscured by bars.
- final View rootView = findViewById(R.id.root);
- ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, windowInsets) -> {
+ mRootView = findViewById(R.id.root);
+ ViewCompat.setOnApplyWindowInsetsListener(mRootView, (view, windowInsets) -> {
final View linearLayout = findViewById(R.id.linear_layout);
final Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
final MarginLayoutParams params = (MarginLayoutParams) linearLayout.getLayoutParams();
@@ -64,6 +72,29 @@
linearLayout.setLayoutParams(params);
return WindowInsetsCompat.CONSUMED;
});
+
+ if (sIsFinishing) {
+ startFinishSequence();
+ }
+ }
+
+ private void disableActivityTransitions() {
+ overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, 0, 0);
+ overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, 0, 0);
+ }
+
+ @Override
+ protected void applyForwardTransition() {
+ if (!sIsFinishing) {
+ super.applyForwardTransition();
+ }
+ }
+
+ @Override
+ protected void applyBackwardTransition() {
+ if (!sIsFinishing) {
+ super.applyBackwardTransition();
+ }
}
@Override
@@ -72,40 +103,67 @@
}
@Override
+ public Resources.Theme getTheme() {
+ Resources.Theme theme = super.getTheme();
+ if (sIsFinishing) {
+ if (mEdgeToEdgeWallpaperBackgroundTheme == null) {
+ theme.applyStyle(R.style.EdgeToEdgeWallpaperBackground, true);
+ mEdgeToEdgeWallpaperBackgroundTheme = theme;
+ }
+ return mEdgeToEdgeWallpaperBackgroundTheme;
+ }
+ return theme;
+ }
+
+ @Override
public void onNavigateNext() {
- startFinishSequence();
+ if (!sIsFinishing) {
+ sIsFinishing = true;
+ startActivity(getIntent());
+ finish();
+ disableActivityTransitions();
+ }
+ hideNextButton();
}
private void startFinishSequence() {
- if (mIsFinishing) {
- return;
- }
- mIsFinishing = true;
-
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
hideNextButton();
// Begin outro animation.
- animateOut();
+ if (mRootView.isAttachedToWindow()) {
+ mHandler.post(() -> animateOut());
+ } else {
+ mRootView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mHandler.post(() -> animateOut());
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ // Do nothing
+ }
+ });
+ }
}
private void animateOut() {
- final View rootView = findViewById(R.id.root);
- final int cx = (rootView.getLeft() + rootView.getRight()) / 2;
- final int cy = (rootView.getTop() + rootView.getBottom()) / 2;
+ final int cx = (mRootView.getLeft() + mRootView.getRight()) / 2;
+ final int cy = (mRootView.getTop() + mRootView.getBottom()) / 2;
final float fullRadius = (float) Math.hypot(cx, cy);
Animator anim =
- ViewAnimationUtils.createCircularReveal(rootView, cx, cy, fullRadius, 0f);
+ ViewAnimationUtils.createCircularReveal(mRootView, cx, cy, fullRadius, 0f);
anim.setDuration(900);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- rootView.setVisibility(View.VISIBLE);
+ mRootView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
- rootView.setVisibility(View.INVISIBLE);
+ mRootView.setVisibility(View.INVISIBLE);
mHandler.post(() -> {
if (LOGV) {
Log.v(TAG, "Animation ended");