blob: 0546ded78207bfd45407be7a0ac36f55f8373c2e [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.embedding.android;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Splash screen configuration for a given Flutter experience.
*
* <p>Implementations provide a visual representation of a splash screen in {@link
* #createSplashView(Context, Bundle)}, and implement a transition from the splash UI to Flutter's
* UI in {@link #transitionToFlutter(Runnable)}.
*/
public interface SplashScreen {
/**
* Creates a {@code View} to be displayed as a splash screen before Flutter renders its first
* frame.
*
* <p>This method can be called at any time, and may be called multiple times depending on Android
* configuration changes that require recreation of a view hierarchy. Implementers that provide a
* stateful splash view, such as one with animations, should take care to migrate that animation
* state from the previously returned splash view to the newly created splash view.
*/
@Nullable
View createSplashView(@NonNull Context context, @Nullable Bundle savedInstanceState);
/**
* Invoked by Flutter when Flutter has rendered its first frame, and would like the {@code
* splashView} to disappear.
*
* <p>The provided {@code onTransitionComplete} callback must be invoked when the splash {@code
* View} has finished transitioning itself away. The splash {@code View} will be removed and
* destroyed when the callback is invoked.
*/
void transitionToFlutter(@NonNull Runnable onTransitionComplete);
/**
* Returns {@code true} if the splash {@code View} built by this {@code SplashScreen} remembers
* its transition progress across configuration changes by saving that progress to {@code View}
* state. Returns {@code false} otherwise.
*
* <p>The typical return value for this method is {@code false}. When the return value is {@code
* false}, the following can happen:
*
* <ol>
* <li>Splash {@code View} begins transitioning to the Flutter UI.
* <li>A configuration change occurs, like an orientation change, and the {@code Activity} is
* re-created, along with the {@code View} hierarchy.
* <li>The remainder of the splash transition is skipped and the Flutter UI is displayed.
* </ol>
*
* In the vast majority of cases, skipping a little bit of the splash transition should be
* acceptable. Most users will never experience such a situation, and those that do are unlikely
* to notice the visual artifact. However, a workaround is available for those developers who need
* it.
*
* <p>Returning {@code true} from this method will cause the given splash {@code View} to be
* displayed in the {@code View} hierarchy, even if Flutter has already rendered its first frame.
* It is then the responsibility of the splash {@code View} to remember its previous transition
* progress, restart any animations, and then trigger its completion callback when appropriate. It
* is also the responsibility of the splash {@code View} to immediately invoke the completion
* callback if it has already completed its transition. By meeting these requirements, and
* returning {@code true} from this method, the splash screen experience will be completely
* seamless, including configuration changes.
*/
// We suppress NewApi because the CI linter thinks that "default" methods are unsupported.
@SuppressLint("NewApi")
default boolean doesSplashViewRememberItsTransition() {
return false;
}
/**
* Returns whatever state is necessary to restore a splash {@code View} after destruction and
* recreation, e.g., orientation change.
*/
// We suppress NewApi because the CI linter thinks that "default" methods are unsupported.
@SuppressLint("NewApi")
@Nullable
default Bundle saveSplashScreenState() {
return null;
}
}