Màn hình chờ

Kể từ Android 12, SplashScreen API cho phép các ứng dụng chạy bằng ảnh động, bao gồm chuyển động trong ứng dụng khi khởi chạy, màn hình chờ hiển thị biểu tượng ứng dụng và chuyển đổi cho chính ứng dụng đó. SplashScreen là một Window và do đó bao gồm một Activity.

Hình 1. Màn hình chờ.

Trải nghiệm màn hình chờ mang đến các thành phần thiết kế tiêu chuẩn cho mỗi lần khởi chạy ứng dụng. Tuy nhiên, bạn cũng có thể tuỳ chỉnh trải nghiệm này để duy trì thương hiệu độc đáo của mình.

Ngoài việc sử dụng API nền tảng SplashScreen, bạn cũng có thể dùng thư viện tương thích SplashScreen, thư viện này bao bọc API SplashScreen.

Cách hoạt động của màn hình chờ

Khi người dùng chạy một ứng dụng trong lúc quy trình của ứng dụng đó không chạy (khởi động nguội) hoặc Activity không được tạo (khởi động ấm), thì những sự kiện sau sẽ xảy ra:

  1. Hệ thống hiển thị màn hình chờ bằng cách sử dụng các giao diện và bất kỳ ảnh động nào mà bạn xác định.

  2. Khi ứng dụng sẵn sàng, màn hình chờ sẽ đóng và ứng dụng sẽ hiển thị.

Màn hình chờ không bao giờ hiển thị trong khi khởi động nóng.

Các thành phần và cơ chế của màn hình chờ

Các phần tử của màn hình chờ được xác định bằng các tệp tài nguyên XML trong tệp kê khai Android. Có các phiên bản chế độ sáng và tối cho mỗi phần tử.

Các thành phần có thể tùy chỉnh của màn hình chờ bao gồm biểu tượng ứng dụng, nền biểu tượng và nền cửa sổ:

Hình ảnh cho thấy các thành phần có trong màn hình chờ
Hình 2. Các phần tử có thể tuỳ chỉnh của màn hình chờ.

Hãy xem xét các yếu tố sau, được minh hoạ trong hình 2:

1 Biểu tượng ứng dụng phải là một vectơ vẽ được. Ảnh có thể là ảnh tĩnh hoặc ảnh động. Mặc dù ảnh động có thể có thời lượng không giới hạn, nhưng bạn không nên vượt quá 1.000 mili giây. Biểu tượng trình chạy là biểu tượng mặc định.

2 Nền biểu tượng là không bắt buộc và hữu ích nếu bạn cần tăng độ tương phản giữa biểu tượng và nền cửa sổ. Nếu bạn sử dụng biểu tượng thích ứng, nền của biểu tượng sẽ hiển thị nếu có đủ độ tương phản với nền cửa sổ.

3 Giống như biểu tượng thích ứng, 1/3 nền trước được che giấu.

4 Nền cửa sổ có màu đục đơn sắt. Nếu nền cửa sổ được đặt có màu trơn, nó sẽ được dùng theo mặc định nếu bạn không đặt thuộc tính này.

Kích thước màn hình chờ

Biểu tượng màn hình chờ sử dụng thông số kỹ thuật giống như các biểu tượng thích ứng như sau:

  • Hình ảnh thương hiệu: kích thước phải là 200×80 dp.
  • Biểu tượng ứng dụng có nền biểu tượng: kích thước này phải là 240×240 dp và vừa với hình tròn có đường kính 160 dp.
  • Biểu tượng ứng dụng không có nền biểu tượng: kích thước này phải là 288×288 dp và vừa với hình tròn có đường kính 192 dp.

Ví dụ: nếu kích thước đầy đủ của hình ảnh là 300×300 dp, biểu tượng cần phải vừa với hình tròn có đường kính 200 dp. Mọi thứ bên ngoài vòng tròn sẽ trở nên vô hình (che giấu).

Hình ảnh thể hiện nhiều kích thước biểu tượng cho nền đồng nhất và trong suốt
Hình 3. Kích thước biểu tượng màn hình chờ cho nền đồng nhất và trong suốt tương ứng.

Ảnh động trên màn hình chờ và trình tự khởi chạy

Độ trễ bổ sung thường liên quan đến việc khởi chạy ứng dụng khi khởi động nguội. Việc thêm biểu tượng động vào màn hình chờ sẽ làm tăng tính thẩm mỹ và mang lại trải nghiệm cao cấp hơn. Nghiên cứu về người dùng cho thấy thời gian khởi động dự kiến thấp hơn khi xem ảnh động.

Ảnh động trên màn hình chờ được nhúng trong các thành phần trình tự khởi chạy, như minh hoạ trong hình 4.

Hình ảnh thể hiện trình tự khởi chạy trong 12 khung hình liên tiếp, bắt đầu bằng việc nhấn vào biểu tượng trình chạy và lấp đầy màn hình khi màn hình phóng to
Hình 4. Khởi chạy trình tự.
  1. Nhập ảnh động: ảnh động này bao gồm chế độ xem hệ thống cho màn hình chờ. Mã này do hệ thống kiểm soát và không tuỳ chỉnh được.

  2. Màn hình chờ (xuất hiện trong phần "chờ" của trình tự): bạn có thể tuỳ chỉnh màn hình chờ, cho phép bạn cung cấp ảnh động biểu trưng và xây dựng thương hiệu của riêng mình. Tệp này phải đáp ứng các yêu cầu như mô tả trong trang này thì mới hoạt động bình thường.

  3. Thoát khỏi ảnh động: ảnh này bao gồm ảnh động ẩn màn hình chờ. Nếu bạn muốn tuỳ chỉnh giao diện, hãy sử dụng SplashScreenView và biểu tượng tương ứng. Bạn có thể chạy bất kỳ ảnh động nào trên đó, với các chế độ cài đặt về biến đổi, độ mờ và màu sắc. Trong trường hợp này, hãy xoá màn hình chờ theo cách thủ công khi ảnh động hoàn tất.

Khi chạy hoạt ảnh biểu tượng, bạn sẽ có thể bỏ qua trình tự trong các trường hợp ứng dụng đã sẵn sàng trước đó. Ứng dụng kích hoạt onResume() hoặc màn hình chờ sẽ tự động hết thời gian chờ, vì vậy, hãy đảm bảo người dùng có thể bỏ qua chuyển động một cách thoải mái. Bạn chỉ phải loại bỏ màn hình chờ bằng onResume() khi ứng dụng ổn định từ góc độ hình ảnh, do đó, không cần thêm vòng quay nào. Việc cung cấp giao diện chưa hoàn chỉnh có thể gây khó chịu cho người dùng và có thể gây ấn tượng khó dự đoán hoặc thiếu đánh bóng.

Yêu cầu ảnh động trên màn hình chờ

Màn hình chờ của bạn phải tuân thủ các thông số kỹ thuật sau:

  • Đặt màu nền cho một cửa sổ mà không có độ trong suốt. Chế độ ban ngày và ban đêm được hỗ trợ với thư viện ứng dụng SplashScreen.

  • Đảm bảo biểu tượng động đáp ứng các thông số kỹ thuật sau:

    • Định dạng: biểu tượng phải ở định dạng XML AnimatedVectorDrawable (AVD).
    • Kích thước: một biểu tượng AVD phải có kích thước gấp bốn lần biểu tượng thích ứng, như sau:
      • Khu vực biểu tượng phải là 432 dp – nói cách khác, gấp 4 lần diện tích 108 dp của biểu tượng thích ứng không được che giấu.
      • Hai phần ba bên trong của hình ảnh hiển thị trên biểu tượng trình chạy và phải có kích thước 288 dp – nói cách khác, gấp 4 lần 72 dp (tạo thành vùng che giấu bên trong của một biểu tượng thích ứng).
    • Thời lượng: chúng tôi đề xuất không quá 1.000 mili giây trên điện thoại. Bạn có thể sử dụng thời gian khởi động trễ, nhưng không được dài hơn 166 mili giây. Nếu thời gian khởi động ứng dụng dài hơn 1.000 mili giây, hãy cân nhắc sử dụng ảnh động lặp lại.
  • Thiết lập thời gian thích hợp để loại bỏ màn hình chờ, điều này xảy ra khi ứng dụng của bạn vẽ khung hình đầu tiên. Bạn có thể tuỳ chỉnh thêm phần này như mô tả trong phần về cách giữ màn hình chờ trên màn hình trong thời gian dài hơn.

Tài nguyên trên màn hình chờ

Hình 5. Ví dụ về AVD.

Tải ví dụ về bộ công cụ dành cho người mới bắt đầu xuống. Bộ công cụ này minh hoạ cách tạo, định dạng và xuất ảnh động thành AVD. Gói này bao gồm những công cụ sau:

  • Tệp dự án Adobe After Effects của ảnh động.
  • Tệp AVD XML đã xuất cuối cùng.
  • Ảnh GIF mẫu của ảnh động.

Bằng việc tải các tệp này xuống, bạn đồng ý với Điều khoản dịch vụ của Google.

Chính sách quyền riêng tư của Google mô tả cách chúng tôi xử lý dữ liệu trong dịch vụ này.

Tùy chỉnh màn hình chờ trong ứng dụng

Theo mặc định, SplashScreen sử dụng windowBackground của giao diện nếu windowBackground là một màu duy nhất. Để tuỳ chỉnh màn hình chờ, hãy thêm các thuộc tính vào giao diện của ứng dụng.

Bạn có thể tuỳ chỉnh màn hình chờ của ứng dụng bằng cách thực hiện bất kỳ thao tác nào sau đây:

  • Đặt các thuộc tính giao diện để thay đổi giao diện.

  • Lưu giữ quảng cáo trên màn hình trong thời gian dài hơn.

  • Tuỳ chỉnh ảnh động để đóng màn hình chờ.

Bắt đầu

Thư viện SplashScreen chính đưa màn hình chờ của Android 12 đến tất cả thiết bị từ API 23. Để thêm đoạn mã này vào dự án, hãy thêm đoạn mã sau vào tệp build.gradle:

Groovy

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-splashscreen:1.0.0")
}

Đặt giao diện cho màn hình chờ để thay đổi giao diện

Bạn có thể chỉ định các thuộc tính sau trong giao diện Activity để tuỳ chỉnh màn hình chờ cho ứng dụng của mình. Nếu đã triển khai màn hình chờ cũ sử dụng các thuộc tính như android:windowBackground, hãy cân nhắc việc cung cấp tệp tài nguyên thay thế cho Android 12 trở lên.

  1. Sử dụng windowSplashScreenBackgroundđể tô nền bằng một màu đơn sắc:

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. Sử dụng windowSplashScreenAnimatedIcon để thay thế biểu tượng ở giữa cửa sổ bắt đầu.

    Chỉ đối với ứng dụng nhắm đến Android 12 (API cấp 32), hãy làm như sau:

    Nếu có thể tạo và vẽ được đối tượng thông qua AnimationDrawableAnimatedVectorDrawable, hãy đặt windowSplashScreenAnimationDuration để phát ảnh động trong khi hiển thị cửa sổ bắt đầu. Điều này là không bắt buộc đối với Android 13, vì thời lượng được dự đoán trực tiếp từ AnimatedVectorDrawable.

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. Sử dụng windowSplashScreenAnimationDurationbiểu thị thời lượng của ảnh động trên biểu tượng màn hình chờ. Việc đặt thuộc tính này không ảnh hưởng đến thời gian thực tế hiển thị màn hình chờ, nhưng bạn có thể truy xuất màn hình chờ này khi tuỳ chỉnh ảnh động thoát khỏi màn hình chờ bằng cách sử dụng SplashScreenView.getIconAnimationDuration. Hãy xem phần sau đây về cách giữ màn hình chờ trên màn hình trong thời gian dài hơn để biết thêm thông tin chi tiết.

    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    
  4. Sử dụng windowSplashScreenIconBackgroundColor để đặt nền phía sau biểu tượng màn hình chờ. Điều này hữu ích nếu nền cửa sổ và biểu tượng không có đủ độ tương phản.

    <item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
    
  5. Bạn có thể sử dụng windowSplashScreenBrandingImage để đặt hình ảnh hiển thị ở cuối màn hình chờ. Tuy nhiên, theo nguyên tắc thiết kế, bạn không nên sử dụng hình ảnh thương hiệu.

    <item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
    
  6. Bạn có thể sử dụng windowSplashScreenBehavior để chỉ định xem ứng dụng của bạn có luôn hiển thị biểu tượng trên màn hình chờ trong Android 13 trở lên hay không. Giá trị mặc định là 0, hiển thị biểu tượng trên màn hình chờ nếu hoạt động chạy đặt splashScreenStyle thành SPLASH_SCREEN_STYLE_ICON hoặc tuân theo hành vi của hệ thống nếu hoạt động chạy không chỉ định kiểu. Nếu bạn không bao giờ hiển thị màn hình chờ trống và luôn muốn hiển thị biểu tượng động, hãy đặt thuộc tính này thành giá trị icon_preferred.

    <item name="android:windowSplashScreenBehavior">icon_preferred</item>
    

Giữ màn hình chờ trên màn hình lâu hơn

Màn hình chờ sẽ đóng ngay khi ứng dụng vẽ khung hình đầu tiên. Nếu cần tải một lượng dữ liệu nhỏ, chẳng hạn như tải không đồng bộ các chế độ cài đặt trong ứng dụng từ ổ đĩa cục bộ, bạn có thể sử dụng ViewTreeObserver.OnPreDrawListener để tạm ngưng ứng dụng vẽ khung hình đầu tiên.

Nếu hoạt động bắt đầu kết thúc trước khi vẽ (ví dụ: không thiết lập khung hiển thị nội dung và hoàn tất trước onResume), thì bạn sẽ không cần sử dụng trình nghe trước khi vẽ.

Kotlin

// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set the layout for the content view.
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check whether the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready. Start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content isn't ready. Suspend.
                    false
                }
            }
        }
    )
}

Java

// Create a new event for the activity.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the layout for the content view.
    setContentView(R.layout.main_activity);

    // Set up an OnPreDrawListener to the root view.
    final View content = findViewById(android.R.id.content);
    content.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // Check whether the initial data is ready.
                    if (mViewModel.isReady()) {
                        // The content is ready. Start drawing.
                        content.getViewTreeObserver().removeOnPreDrawListener(this);
                        return true;
                    } else {
                        // The content isn't ready. Suspend.
                        return false;
                    }
                }
            });
}

Tùy chỉnh ảnh động để đóng màn hình chờ

Có thể tùy chỉnh thêm ảnh động trên màn hình chờ quaActivity.getSplashScreen().

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    splashScreen.setOnExitAnimationListener { splashScreenView ->
        // Create your custom animation.
        val slideUp = ObjectAnimator.ofFloat(
            splashScreenView,
            View.TRANSLATION_Y,
            0f,
            -splashScreenView.height.toFloat()
        )
        slideUp.interpolator = AnticipateInterpolator()
        slideUp.duration = 200L

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.doOnEnd { splashScreenView.remove() }

        // Run your animation.
        slideUp.start()
    }
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
        final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
                splashScreenView,
                View.TRANSLATION_Y,
                0f,
                -splashScreenView.getHeight()
        );
        slideUp.setInterpolator(new AnticipateInterpolator());
        slideUp.setDuration(200L);

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                splashScreenView.remove();
            }
        });

        // Run your animation.
        slideUp.start();
    });
}

Khi bắt đầu lệnh gọi lại này, vectơ động vẽ được trên màn hình chờ sẽ bắt đầu. Tùy thuộc vào thời điểm khởi chạy ứng dụng, đối tượng vẽ có thể nằm ở giữa ảnh động của ứng dụng. Sử dụngSplashScreenView.getIconAnimationStartđể biết thời điểm bắt đầu ảnh động. Có thể tính thời lượng còn lại của ảnh động biểu tượng như sau:

Kotlin

// Get the duration of the animated vector drawable.
val animationDuration = splashScreenView.iconAnimationDuration
// Get the start time of the animation.
val animationStart = splashScreenView.iconAnimationStart
// Calculate the remaining duration of the animation.
val remainingDuration = if (animationDuration != null && animationStart != null) {
    (animationDuration - Duration.between(animationStart, Instant.now()))
        .toMillis()
        .coerceAtLeast(0L)
} else {
    0L
}

Java

// Get the duration of the animated vector drawable.
Duration animationDuration = splashScreenView.getIconAnimationDuration();
// Get the start time of the animation.
Instant animationStart = splashScreenView.getIconAnimationStart();
// Calculate the remaining duration of the animation.
long remainingDuration;
if (animationDuration != null && animationStart != null) {
    remainingDuration = animationDuration.minus(
            Duration.between(animationStart, Instant.now())
    ).toMillis();
    remainingDuration = Math.max(remainingDuration, 0L);
} else {
    remainingDuration = 0L;
}

Tài nguyên khác