หน้าจอแนะนำ

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

รูปที่ 1 หน้าจอเริ่มต้น

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

นอกเหนือจากการใช้ SplashScreen Platform API แล้ว คุณยังใช้ SplashScreen ไลบรารีความเข้ากันได้ซึ่งครอบคลุม 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 พื้นหลังของหน้าต่างประกอบด้วยสีทึบสีเดียว หากตั้งค่าพื้นหลังของหน้าต่างเป็นสีธรรมดา ระบบจะใช้พื้นหลังนั้น โดยค่าเริ่มต้นหากไม่ได้ตั้งค่าแอตทริบิวต์

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

แหล่งข้อมูลสำหรับหน้าจอเริ่มต้น

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

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

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

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

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

ปรับแต่งหน้าจอเริ่มต้นในแอป

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

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

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

  • แสดงไว้บนหน้าจอเป็นระยะเวลานานขึ้น

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

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

SplashScreenไลบรารีหลัก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 บนหน้าจอเป็นระยะเวลานานขึ้น

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

เมื่อเริ่มการเรียกกลับนี้ ภาพวาดเวกเตอร์เคลื่อนไหว ในหน้าจอเริ่มต้นจะเริ่มทำงาน รูปภาพอาจอยู่ตรงกลางของภาพเคลื่อนไหว ทั้งนี้ขึ้นอยู่กับระยะเวลาการเปิดตัวแอป drawable ใช้ 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;
}

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