หน้าจอแนะนำ

ตั้งแต่ Android 12 เป็นต้นไป SplashScreen API จะช่วยให้แอปเปิดขึ้นพร้อมภาพเคลื่อนไหวได้ ซึ่งรวมถึงการเคลื่อนไหวในแอปเมื่อเปิด หน้าจอแนะนำที่แสดงไอคอนแอป และการเปลี่ยนไปยังแอป SplashScreen เป็น Window และจึงครอบคลุม Activity

รูปที่ 1 หน้าจอแนะนำ

หน้าจอแนะนำจะแสดงองค์ประกอบการออกแบบมาตรฐานในการเปิดแอปทุกครั้ง แต่คุณก็ปรับแต่งหน้าจอแนะนำได้เพื่อให้แอปคงเอกลักษณ์ของแบรนด์ไว้

นอกจากการใช้ API แพลตฟอร์ม SplashScreen แล้ว คุณยังใช้ SplashScreen ไลบรารี compat ซึ่งรวม SplashScreen API ไว้ด้วยได้

วิธีการทำงานของหน้าจอแนะนำ

เมื่อผู้ใช้เปิดแอปขณะที่กระบวนการของแอปไม่ทำงาน (การเริ่มต้นแบบ Cold Start) หรือไม่ได้สร้าง Activity (การเริ่มต้นแบบ Warm Start) เหตุการณ์ต่อไปนี้จะเกิดขึ้น

  1. ระบบจะแสดงหน้าจอแนะนำโดยใช้ธีมและภาพเคลื่อนไหวที่คุณกำหนด

  2. เมื่อแอปพร้อมใช้งานแล้ว หน้าจอแนะนำจะปิดไปและแอปจะแสดง

หน้าจอแนะนำจะไม่แสดงขึ้นในระหว่างการเริ่มต้นแบบร้อน

องค์ประกอบและกลไกของหน้าจอแนะนำ

องค์ประกอบของหน้าจอแนะนำจะกำหนดโดยไฟล์ทรัพยากร XML ในไฟล์ Manifest ของ Android แต่ละองค์ประกอบมีเวอร์ชันโหมดสว่างและโหมดมืด

องค์ประกอบที่ปรับแต่งได้ของหน้าจอแนะนำประกอบด้วยไอคอนแอป ไอคอน พื้นหลัง และ พื้นหลังของหน้าต่าง:

รูปภาพแสดงองค์ประกอบที่อยู่ในหน้าจอแนะนำ
รูปที่ 2 องค์ประกอบที่ปรับแต่งได้ของหน้าจอแนะนำ

ลองพิจารณาองค์ประกอบต่อไปนี้ที่แสดงในรูปที่ 2

1 ไอคอนแอปต้องเป็น Vector Drawable ทั้งนี้ อาจเป็นภาพนิ่งหรือภาพเคลื่อนไหวก็ได้ แม้ว่าภาพเคลื่อนไหวจะมีระยะเวลาได้ไม่จำกัด แต่เราขอแนะนำให้ไม่เกิน 1,000 มิลลิวินาที ไอคอน Launcher เป็นค่าเริ่มต้น

2 พื้นหลังไอคอนเป็นองค์ประกอบที่ไม่บังคับและมีประโยชน์ในกรณีต่อไปนี้ คุณต้องการคอนทราสต์ระหว่างไอคอนกับพื้นหลังของหน้าต่างมากขึ้น หากคุณใช้ แบบปรับอัตโนมัติ แสดงพื้นหลังเมื่อคอนทราสต์กับพื้นหลังของหน้าต่างมากพอ

3 พื้นหน้า 1 ใน 3 มีการมาสก์เช่นเดียวกับไอคอนแบบปรับอัตโนมัติ

4 พื้นหลังหน้าต่างประกอบด้วย สีทึบ หากตั้งค่าพื้นหลังของหน้าต่างเป็นสีพื้น ระบบจะใช้สีนั้นโดยค่าเริ่มต้นหากไม่ได้ตั้งค่าแอตทริบิวต์

ขนาดหน้าจอแนะนำ

ไอคอนหน้าจอแนะนำใช้ข้อกำหนดเดียวกันกับ ไอคอนแบบปรับอัตโนมัติ ดังนี้

  • รูปภาพที่มีแบรนด์: รูปภาพนี้ต้องมีขนาด 200×80 dp
  • ไอคอนแอปที่มีพื้นหลังไอคอน: มีขนาด 240×240 dp และพอดีกับวงกลมที่มีเส้นผ่านศูนย์กลาง 160 dp
  • ไอคอนแอปที่ไม่มีพื้นหลังไอคอน: ต้องมีขนาด 288×288 dp และพอดีกับภายใน เส้นผ่านศูนย์กลางของวงกลมขนาด 192 dp

ตัวอย่างเช่น หากรูปภาพขนาดเต็มคือ 300×300 dp ไอคอนต้องพอดีกับวงกลมที่มีเส้นผ่านศูนย์กลาง 200 dp ทุกอย่างที่อยู่นอกวงกลมจะมองไม่เห็น (ถูกมาสก์)

รูปภาพที่แสดงขนาดไอคอนต่างๆ สำหรับพื้นหลังทึบและโปร่งใส
รูปที่ 3 ขนาดไอคอนหน้าจอเริ่มต้นสำหรับ พื้นหลังแข็งและโปร่งใสตามลำดับ

ภาพเคลื่อนไหวหน้าจอแนะนำและลำดับการเปิดตัว

เวลาในการตอบสนองที่เพิ่มขึ้นมักจะเชื่อมโยงกับการเปิดใช้แอปใน Cold Start การเพิ่มไอคอนเคลื่อนไหวลงในหน้าจอแนะนำจะช่วยดึงดูดสายตาและมอบประสบการณ์การใช้งานที่พรีเมียมยิ่งขึ้น การวิจัยผู้ใช้แสดงให้เห็นว่าสตาร์ทอัพที่รับรู้ เวลาจะน้อยลงเมื่อดูภาพเคลื่อนไหว

ภาพเคลื่อนไหวหน้าจอแนะนำฝังอยู่ในคอมโพเนนต์ลำดับการเปิดตัว เช่น ที่แสดงในรูปที่ 4

รูปภาพแสดงลำดับการเปิดใช้งานใน 12 เฟรมต่อเนื่องกัน เริ่มต้นจากการแตะไอคอน Launcher แล้วขยายเต็มหน้าจอเมื่อขยาย
รูปที่ 4 ลำดับการเปิดตัว
  1. ป้อนภาพเคลื่อนไหว ซึ่งประกอบไปด้วยมุมมองระบบในหน้าจอเริ่มต้น ทั้งนี้ ถูกควบคุมโดยระบบและปรับแต่งไม่ได้

  2. ภาพหน้าจอแนะนำ (แสดงในช่วง "รอ" ของลำดับ): คุณปรับแต่งภาพหน้าจอแนะนำได้ ซึ่งจะช่วยให้คุณใส่ภาพเคลื่อนไหวของโลโก้และการสร้างแบรนด์ของคุณเองได้ และต้องเป็นไปตามข้อกำหนดที่อธิบายไว้ในหน้านี้จึงจะทำงานได้อย่างถูกต้อง

  3. ออกจากภาพเคลื่อนไหว: ประกอบด้วยภาพเคลื่อนไหวที่ซ่อนหน้าจอแนะนำ หากต้องการปรับแต่ง ให้ใช้ SplashScreenView และไอคอน คุณเรียกใช้ภาพเคลื่อนไหวใดก็ได้ในองค์ประกอบเหล่านี้ โดยมีการตั้งค่าสำหรับการเปลี่ยนรูปแบบ ความทึบแสง และสี ในกรณีนี้ ให้นำหน้าจอแนะนำออกด้วยตนเองเมื่อภาพเคลื่อนไหวเสร็จแล้ว

เมื่อแสดงภาพเคลื่อนไหวของไอคอน การเปิดตัวแอปจะให้ตัวเลือกในการข้ามลำดับในกรณีที่แอปพร้อมใช้งานเร็วกว่านั้น แอปจะทริกเกอร์ onResume() หรือหน้าจอเริ่มต้นหมดเวลาโดยอัตโนมัติ ดังนั้นโปรดตรวจสอบว่า ข้ามได้อย่างสะดวกสบาย หน้าจอแนะนำต้องปิดด้วย onResume() เท่านั้นเมื่อแอปทำงานได้อย่างเสถียรจากมุมมองภาพ จึงไม่จำเป็นต้องมีภาพสปินเนอร์เพิ่มเติม การเปิดตัวอินเทอร์เฟซที่ยังไม่สมบูรณ์อาจทำให้ผู้ใช้สับสนและอาจทำให้ผู้ใช้รู้สึกว่าคุณไม่แน่ใจหรือทำงานไม่เรียบร้อย

ข้อกำหนดสำหรับภาพเคลื่อนไหวหน้าจอแนะนำ

หน้าจอแนะนำต้องเป็นไปตามข้อกำหนดต่อไปนี้

  • ตั้งค่าสีพื้นหลังของหน้าต่างเดียวแบบไม่โปร่งใส ระบบรองรับโหมดกลางวันและกลางคืนด้วยSplashScreen compat library

  • ตรวจสอบว่าไอคอนแบบเคลื่อนไหวเป็นไปตามข้อกำหนดต่อไปนี้

    • รูปแบบ: ไอคอนต้องเป็น AnimatedVectorDrawable (AVD) XML
    • ขนาด: ไอคอน AVD ต้องมีขนาดใหญ่กว่าไอคอนแบบปรับอัตโนมัติ 4 เท่า ดังนี้
      • พื้นที่ของไอคอนต้องเท่ากับ 432 dp หรือ 4 เท่าของพื้นที่ 108 dp ของไอคอนแบบปรับเปลี่ยนได้ซึ่งไม่ได้มาสก์
      • พื้นที่ 2 ใน 3 ด้านในของรูปภาพจะปรากฏบนไอคอน Launcher และต้องเป็น 288 dp หรือ 4 คูณ 72 dp ประกอบขึ้นเป็นบริเวณที่มาสก์ด้านในของไอคอนแบบปรับอัตโนมัติ
    • ระยะเวลา: เราขอแนะนำว่าไม่ควรเกิน 1,000 มิลลิวินาทีบนโทรศัพท์ คุณสามารถใช้ การเริ่มต้นแบบล่าช้า แต่ต้องต้องไม่เกิน 166 มิลลิวินาที หากแอป เวลาเริ่มต้นนานกว่า 1,000 มิลลิวินาที ให้พิจารณาภาพเคลื่อนไหวแบบวนซ้ำ
  • กำหนดเวลาที่เหมาะสมในการปิดหน้าจอแนะนำ ซึ่งจะเกิดขึ้นเมื่อ ที่แอปวาดเฟรมแรก คุณปรับแต่งค่านี้เพิ่มเติมได้ตามที่อธิบายไว้ ในส่วนที่เกี่ยวกับ การทำให้หน้าจอเริ่มต้น (Splash Screen) แสดงบนหน้าจอเป็นเวลานาน

ทรัพยากรหน้าจอแนะนำ

รูปที่ 5 ตัวอย่าง AVD

ดาวน์โหลดตัวอย่างชุดเริ่มต้นซึ่งสาธิตวิธีสร้าง จัดรูปแบบ และส่งออกภาพเคลื่อนไหวเป็น AVD ซึ่งรวมถึงสิ่งต่อไปนี้

  • ไฟล์โปรเจ็กต์ Adobe After Effects ของภาพเคลื่อนไหว
  • ไฟล์ XML ของ AVD ที่ส่งออกเวอร์ชันสุดท้าย
  • ตัวอย่าง GIF ของภาพเคลื่อนไหว

การดาวน์โหลดไฟล์เหล่านี้หมายความว่าคุณยอมรับข้อกำหนดในการให้บริการของ Google

นโยบายความเป็นส่วนตัวของ Google อธิบายวิธีการจัดการข้อมูลในบริการนี้

ปรับแต่งหน้าจอแนะนำในแอป

โดยค่าเริ่มต้น SplashScreen จะใช้ windowBackground ของธีมหาก windowBackground เป็นสีเดียว หากต้องการปรับแต่งหน้าจอแนะนำ ให้เพิ่มแอตทริบิวต์ลงในธีมแอป

คุณปรับแต่งหน้าจอแนะนำของแอปได้โดยทำอย่างใดอย่างหนึ่งต่อไปนี้

  • ตั้งค่าแอตทริบิวต์ของธีมเพื่อเปลี่ยนลักษณะที่ปรากฏ

  • ให้อยู่บนหน้าจอเป็นเวลานานขึ้น

  • ปรับแต่งภาพเคลื่อนไหวสำหรับการปิดหน้าจอแนะนำ

เริ่มต้นใช้งาน

ไลบรารี SplashScreen หลักจะนําหน้าจอแนะนำของ Android 12 ไปใช้กับอุปกรณ์ทั้งหมดจาก API 23 หากต้องการเพิ่มรายการนี้ลงในโครงการ ให้เพิ่มข้อมูลโค้ดต่อไปนี้ใน ไฟล์ build.gradle ของคุณ:

Groovy

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

Kotlin

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

ตั้งค่าธีมสำหรับหน้าจอแนะนำเพื่อเปลี่ยนลักษณะที่ปรากฏ

คุณสามารถระบุแอตทริบิวต์ต่อไปนี้ในธีม Activity เพื่อปรับแต่งหน้าจอแนะนำสำหรับแอปได้ หากคุณมีการใช้งานหน้าจอแนะนำเดิมที่ใช้แอตทริบิวต์อย่าง android:windowBackground อยู่แล้ว ให้พิจารณาระบุไฟล์ทรัพยากรอื่นสำหรับ Android 12 ขึ้นไป

  1. ใช้ windowSplashScreenBackground เพื่อเติมพื้นหลังด้วยสีเดียว

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. ใช้ windowSplashScreenAnimatedIcon เพื่อแทนที่ไอคอนตรงกลางของหน้าต่างเริ่มต้น

    สำหรับแอปที่กำหนดเป้าหมายเป็น Android 12 (API ระดับ 32) เท่านั้น ให้ทำดังนี้

    หากวัตถุเคลื่อนไหวได้และสามารถวาดผ่านได้ AnimationDrawable และ AnimatedVectorDrawable ตั้งค่า windowSplashScreenAnimationDuration เป็น เล่นภาพเคลื่อนไหวขณะที่แสดงหน้าต่างเริ่มต้น แต่ไม่จำเป็นต้องระบุสำหรับ Android 13 เนื่องจากระบบจะอนุมานระยะเวลาจาก AnimatedVectorDrawable โดยตรง

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. ใช้ windowSplashScreenAnimationDuration เพื่อระบุระยะเวลาของภาพเคลื่อนไหวไอคอนหน้าจอแนะนำ การตั้งค่านี้จะไม่มีผลกับเวลาจริงที่หน้าจอแนะนำแสดง แต่คุณสามารถเรียกข้อมูลได้เมื่อปรับแต่งภาพเคลื่อนไหวของหน้าจอแนะนำที่ออกโดยใช้ SplashScreenView.getIconAnimationDuration โปรดดูส่วนต่อไปนี้เกี่ยวกับ การทำให้หน้าจอเริ่มต้น (Splash Screen) อยู่บนหน้าจอเป็นเวลานาน เพื่อดูรายละเอียดเพิ่มเติม

    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    
  4. ใช้ windowSplashScreenIconBackgroundColor เพื่อตั้งค่าพื้นหลังด้านหลังไอคอนหน้าจอแนะนำ ซึ่งจะเป็นประโยชน์หากมี พื้นหลังของหน้าต่างและไอคอนตัดกันไม่เพียงพอ

    <item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
    
  5. คุณสามารถใช้ windowSplashScreenBrandingImage เพื่อกำหนดให้รูปภาพแสดงที่ด้านล่างของหน้าจอแนะนำ อย่างไรก็ตาม หลักเกณฑ์การออกแบบไม่ควรใช้รูปภาพแสดงแบรนด์

    <item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
    
  6. คุณสามารถใช้ windowSplashScreenBehavior เพื่อระบุว่าแอปของคุณจะแสดงไอคอน บนหน้าจอแนะนำเสมอหรือไม่ Android 13 ขึ้นไป ค่าเริ่มต้นคือ 0 ซึ่งจะแสดงไอคอนบน หน้าจอเริ่มต้นหากกิจกรรมการเปิดใช้งานตั้งค่า splashScreenStyle เป็น SPLASH_SCREEN_STYLE_ICON, หรือทำตามการทำงานของระบบ หากกิจกรรมการเปิดไม่ได้ระบุ สไตล์ หากไม่ต้องการแสดงหน้าจอแนะนำที่ว่างเปล่าและต้องการให้ไอคอนเคลื่อนไหวแสดงอยู่เสมอ ให้ตั้งค่านี้เป็นค่า icon_preferred

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

แสดงหน้าจอแนะนำบนหน้าจอเป็นเวลานานขึ้น

หน้าจอแนะนำจะปิดทันทีที่แอปวาดเฟรมแรก หากคุณ ต้องโหลดข้อมูลจำนวนน้อย เช่น การโหลดการตั้งค่าในแอปจาก แบบไม่พร้อมกันของดิสก์ในตัวเครื่อง คุณสามารถใช้ ViewTreeObserver.OnPreDrawListener เพื่อระงับแอปไม่ให้วาดเฟรมแรก

ถ้ากิจกรรมเริ่มต้นเสร็จสิ้นก่อนวาด เช่น การตั้งค่าการดูเนื้อหาและสิ้นสุดก่อนวันที่ onResume - การวาดล่วงหน้า คุณไม่จำเป็นต้องฟัง

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;
                    }
                }
            });
}

ปรับแต่งภาพเคลื่อนไหวสำหรับการปิดหน้าจอแนะนำ

คุณปรับแต่งภาพเคลื่อนไหวของหน้าจอแนะนำเพิ่มเติมได้ผ่าน Activity.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();
    });
}

ในช่วงเริ่มต้นของการเรียกกลับนี้ เวกเตอร์ที่เคลื่อนไหวได้แบบวาดได้ ในหน้าจอเริ่มต้น (Splash Screen) จะเริ่มขึ้น ทั้งนี้ขึ้นอยู่กับระยะเวลาการเปิดตัวแอป โฆษณาที่ถอนออกได้อาจอยู่ระหว่างภาพเคลื่อนไหว ใช้ SplashScreenView.getIconAnimationStart เพื่อให้ทราบว่าภาพเคลื่อนไหวเริ่มเมื่อใด คุณสามารถคำนวณระยะเวลาที่เหลือของ ภาพเคลื่อนไหวของไอคอน

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;
}

แหล่งข้อมูลเพิ่มเติม