รองรับโหมดหลายหน้าต่าง

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

รูปที่ 1 แสดง 2 แอปข้างกันในโหมดแยกหน้าจอ

ดูวิธีการเข้าถึงโหมดแยกหน้าจอในโทรศัพท์สำหรับผู้ใช้ได้ที่ดู 2 แอปพร้อมกันในโทรศัพท์ Pixel

ฟีเจอร์มัลติวินโดว์เฉพาะเวอร์ชัน

ประสบการณ์ของผู้ใช้ในโหมดหลายหน้าต่างจะขึ้นอยู่กับเวอร์ชันของ Android และประเภทของอุปกรณ์ ดังนี้

  • Android 7.0 (API ระดับ 24) ได้เปิดตัวโหมดแยกหน้าจอบนอุปกรณ์หน้าจอขนาดเล็ก และโหมดภาพซ้อนภาพบนอุปกรณ์บางรุ่น

    • โหมดแยกหน้าจอจะแสดง 2 แอปบนหน้าจอ โดยแสดงแอป ข้างกันหรือแสดงแอปหนึ่งเหนืออีกแอปหนึ่ง ผู้ใช้สามารถลากเส้นแบ่ง ที่คั่นระหว่าง 2 แอปเพื่อขยายแอปหนึ่งให้ใหญ่ขึ้นและอีกแอปให้เล็กลง

    • โหมดการแสดงภาพซ้อนภาพช่วยให้ผู้ใช้เล่นวิดีโอต่อได้ ขณะโต้ตอบกับแอปอื่น (ดูการรองรับการแสดงภาพซ้อนภาพ)

    • โหมดการแสดงหน้าต่างบนเดสก์ท็อป ซึ่งผู้ใช้สามารถปรับขนาดแต่ละกิจกรรมได้อย่างอิสระ สามารถเปิดใช้ได้โดยผู้ผลิตอุปกรณ์ที่มีหน้าจอขนาดใหญ่

      คุณกำหนดค่าวิธีที่แอปจัดการโหมดหลายหน้าต่างได้โดยการระบุ ขนาดขั้นต่ำที่อนุญาตของกิจกรรม นอกจากนี้ คุณยังปิดใช้ โหมดหลายหน้าต่างสำหรับแอปได้โดยการตั้งค่า resizeableActivity="false" เพื่อให้ระบบแสดง แอปของคุณแบบเต็มหน้าจอเสมอ

  • Android 8.0 (API ระดับ 26) ขยายโหมดภาพซ้อนภาพไปยังอุปกรณ์ที่มีหน้าจอขนาดเล็ก

  • Android 12 (API ระดับ 31) ทำให้โหมดหลายหน้าต่างเป็นลักษณะการทำงานมาตรฐาน

    • ในหน้าจอขนาดใหญ่ (คลาสขนาดหน้าต่างปานกลางหรือขยาย) แพลตฟอร์มจะรองรับแอปทั้งหมดในโหมดหลายหน้าต่างโดยไม่คำนึงถึงการกำหนดค่าแอป หาก resizeableActivity="false" ระบบจะเปลี่ยนแอปเป็น โหมดความเข้ากันได้เมื่อจำเป็นเพื่อให้รองรับขนาดการแสดงผล

    • ในหน้าจอขนาดเล็ก (คลาสขนาดหน้าต่างกะทัดรัด) ระบบจะตรวจสอบminWidthและ minHeight ของกิจกรรมเพื่อพิจารณาว่ากิจกรรมจะเรียกใช้ในโหมดหลายหน้าต่างได้หรือไม่ หาก resizeableActivity="false" ระบบจะป้องกันไม่ให้แอปทำงานใน โหมดหลายหน้าต่างไม่ว่าความกว้างและความสูงขั้นต่ำจะเป็นเท่าใดก็ตาม

  • Android 16 (API ระดับ 36) จะลบล้างการวางแนวหน้าจอ อัตราส่วนภาพ และข้อจำกัดในการปรับขนาด

    • ในหน้าจอขนาดใหญ่ (ความกว้างที่เล็กที่สุด >= 600dp) ระบบจะไม่สนใจ แอตทริบิวต์ของไฟล์ Manifest และ API รันไทม์ที่ใช้ในการจำกัด การวางแนว สัดส่วนภาพ และการปรับขนาดของแอป ซึ่งจะช่วยเพิ่มประสิทธิภาพประสบการณ์ของผู้ใช้ ในอุปกรณ์ทุกรูปแบบ

      ดูวิธียกเว้นเกมจากการเปลี่ยนแปลงใน Android 16 ได้ที่ข้อยกเว้นการวางแนว อัตราส่วนภาพ และการปรับขนาดของแอป

โหมดแยกหน้าจอ

ผู้ใช้เปิดใช้งานโหมดแยกหน้าจอได้โดยทำดังนี้

  1. เปิดหน้าจอล่าสุด
  2. ปัดแอปให้แสดง
  3. กดไอคอนแอปในแถบชื่อแอป
  4. เลือกตัวเลือกเมนูการแยกหน้าจอ
  5. เลือกแอปอื่นจากหน้าจอล่าสุด หรือปิดหน้าจอล่าสุดแล้ว เรียกใช้แอปอื่น

ผู้ใช้ออกจากโหมดแยกหน้าจอได้โดยลากตัวแบ่งหน้าต่างไปที่ขอบของหน้าจอ ไม่ว่าจะขึ้นหรือลง ซ้ายหรือขวา

เปิดตัวพร้อมกัน

หากแอปต้องเข้าถึงเนื้อหาผ่าน Intent คุณสามารถใช้ FLAG_ACTIVITY_LAUNCH_ADJACENT เพื่อเปิดเนื้อหาในหน้าต่าง แบบแยกหน้าจอที่อยู่ติดกัน

FLAG_ACTIVITY_LAUNCH_ADJACENT เปิดตัวใน Android 7.0 (API ระดับ 24) เพื่อให้แอปที่ทำงานในโหมดแยกหน้าจอเปิดใช้กิจกรรมในหน้าต่างที่อยู่ติดกันได้

Android 12L (API ระดับ 32) ขึ้นไปได้ขยายคำจำกัดความของ Flag เพื่อ ให้แอปที่ทำงานแบบเต็มหน้าจอเปิดใช้งานโหมดแยกหน้าจอได้ แล้วจึงเปิด กิจกรรมในหน้าต่างที่อยู่ติดกัน

หากต้องการเปิดกิจกรรมที่อยู่ติดกัน ให้ใช้ FLAG_ACTIVITY_LAUNCH_ADJACENT ร่วมกับ FLAG_ACTIVITY_NEW_TASK เช่น

fun openUrlInAdjacentWindow(url: String) {
    Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url)
       addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or Intent.FLAG_ACTIVITY_NEW_TASK)
    }.also { intent -> startActivity(intent) }
}

วงจรของกิจกรรมในโหมดหลายหน้าต่าง

โหมดหลายหน้าต่างจะไม่เปลี่ยนวงจรของกิจกรรม อย่างไรก็ตาม สถานะ "กลับมาทำงานต่อ" ของแอปในหลายหน้าต่างจะแตกต่างกันใน Android เวอร์ชันต่างๆ

การกลับไปที่ต้นประโยค

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

ฟีเจอร์เล่นต่อหลายรายการยังพร้อมให้บริการในอุปกรณ์บางรุ่นที่ใช้ Android 9 (API ระดับ 28) ด้วย หากต้องการเลือกใช้การกลับมาทำงานต่อหลายรายการในอุปกรณ์ Android 9 ให้เพิ่มข้อมูลเมตาของไฟล์ Manifest ต่อไปนี้

<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

หากต้องการยืนยันว่าอุปกรณ์รองรับข้อมูลเมตาของไฟล์ Manifest นี้หรือไม่ ให้ดู ข้อกำหนดของอุปกรณ์

Android 9

ในโหมดหลายหน้าต่างบน Android 9 (API ระดับ 28) และต่ำกว่า จะมีเพียงกิจกรรม ที่ผู้ใช้โต้ตอบด้วยล่าสุดเท่านั้นที่ใช้งานอยู่ ณ เวลาใดเวลาหนึ่ง กิจกรรมนี้ถือเป็นกิจกรรมบนสุด และเป็นกิจกรรมเดียวในสถานะ RESUMED กิจกรรมอื่นๆ ที่มองเห็นได้ทั้งหมดจะSTARTED แต่จะไม่RESUMED อย่างไรก็ตาม ระบบจะให้ความสำคัญกับกิจกรรมที่มองเห็นได้แต่ไม่ได้ดำเนินการต่อ มากกว่ากิจกรรมที่มองไม่เห็น หากผู้ใช้โต้ตอบกับกิจกรรมที่มองเห็นได้ กิจกรรมนั้นจะกลับมาทำงานต่อ และกิจกรรมที่อยู่ด้านบนสุดก่อนหน้านี้จะเข้าสู่สถานะ STARTED

เมื่อมีกิจกรรมหลายรายการภายในกระบวนการแอปที่ทำงานอยู่รายการเดียว ระบบจะกลับมาทำงานต่อในกิจกรรมที่มีลำดับ z สูงสุด และจะหยุดกิจกรรมอื่นๆ ชั่วคราว

การเปลี่ยนแปลงการกำหนดค่า

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

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

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

สิทธิ์เข้าถึงแหล่งข้อมูลสุดพิเศษ

หากต้องการช่วยรองรับฟีเจอร์การกลับมาเล่นต่อหลายรายการ ให้ใช้ Callback วงจรของ onTopResumedActivityChanged()

ระบบจะเรียกใช้การเรียกกลับเมื่อกิจกรรมได้รับหรือสูญเสียตำแหน่งกิจกรรมที่กลับมาทำงานต่อด้านบน ซึ่งเป็นสิ่งสำคัญเมื่อกิจกรรมใช้ทรัพยากร Singleton ที่แชร์ เช่น ไมโครโฟนหรือกล้อง

override fun onTopResumedActivityChanged(topResumed: Boolean) {
    if (topResumed) {
        // Top resumed activity.
        // Can be a signal to re-acquire exclusive resources.
    } else {
        // No longer the top resumed activity.
    }
}

โปรดทราบว่าแอปอาจสูญเสียทรัพยากรด้วยเหตุผลอื่นๆ เช่น การนำฮาร์ดแวร์ที่แชร์ออก

ไม่ว่าในกรณีใดก็ตาม แอปควรจัดการเหตุการณ์และการเปลี่ยนแปลงสถานะที่ ส่งผลต่อทรัพยากรที่มีอยู่อย่างเหมาะสม

สำหรับแอปที่ใช้กล้อง CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged() จะให้คำแนะนำว่าอาจเป็นเวลาที่เหมาะสมในการลองขอสิทธิ์เข้าถึงกล้อง วิธีนี้พร้อมใช้งานตั้งแต่ Android 10 (API ระดับ 29) เป็นต้นไป

โปรดทราบว่า resizeableActivity=false ไม่ใช่การรับประกันการเข้าถึงกล้องแบบพิเศษ เนื่องจากแอปอื่นๆ ที่ใช้กล้องสามารถเปิดได้บนจอแสดงผลอื่นๆ

รูปที่ 2 กล้องในโหมดหลายหน้าต่าง

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

หลังจากที่แอปได้รับ CameraDevice.StateCallback#onDisconnected() Callback การเรียกใช้ในอุปกรณ์กล้องในครั้งต่อๆ ไปจะทำให้เกิด CameraAccessException

เมตริกของกรอบเวลา

Android 11 (API ระดับ 30) ได้เปิดตัวเมธอด WindowManager ต่อไปนี้ เพื่อระบุขอบเขตของแอปที่ทํางานในโหมดหลายหน้าต่าง

  • getCurrentWindowMetrics(): แสดงผลออบเจ็กต์ WindowMetrics สำหรับ สถานะการแบ่งหน้าต่างปัจจุบันของระบบ
  • getMaximumWindowMetrics(): แสดงผล WindowMetrics สำหรับสถานะการแสดงหน้าต่างที่ใหญ่ที่สุด ที่เป็นไปได้ของระบบ

เมธอดไลบรารี Jetpack WindowManager computeCurrentWindowMetrics() และ computeMaximumWindowMetrics() มีฟังก์ชันการทำงานที่คล้ายกัน ตามลำดับ แต่มีความเข้ากันได้แบบย้อนหลังกับ API ระดับ 14

หากต้องการดูเมตริกสำหรับจอแสดงผลอื่นๆ นอกเหนือจากจอแสดงผลปัจจุบัน ให้ทำดังนี้ (ตามที่แสดงในข้อมูลโค้ด)

  • สร้างบริบทการแสดงผล
  • สร้างบริบทหน้าต่างสำหรับการแสดงผล
  • รับ WindowManager ของบริบทหน้าต่าง
  • รับ WindowMetrics ของพื้นที่แสดงผลสูงสุดที่แอปใช้ได้

val windowMetrics = context.createDisplayContext(display)
                           .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
                           .getSystemService(WindowManager::class.java)
                           .maximumWindowMetrics

วิธีการที่เลิกใช้งานแล้ว

เมธอด Display getSize() และ getMetrics() ถูกเลิกใช้งานใน API ระดับ 30 เพื่อให้ใช้เมธอด WindowManager ใหม่แทน

Android 12 (API ระดับ 31) เลิกใช้งานเมธอด Display getRealSize() และ getRealMetrics() รวมถึงอัปเดตลักษณะการทำงานให้สอดคล้องกับลักษณะการทำงานของ getMaximumWindowMetrics() มากขึ้น

การกำหนดค่าโหมดหลายหน้าต่าง

หากแอปกำหนดเป้าหมายเป็น Android 7.0 (API ระดับ 24) ขึ้นไป คุณจะกำหนดค่าได้ว่ากิจกรรมของแอปจะรองรับโหมดหลายหน้าต่างหรือไม่และรองรับอย่างไร คุณตั้งค่า แอตทริบิวต์ในไฟล์ Manifest เพื่อควบคุมทั้งขนาดและเลย์เอาต์ได้ การตั้งค่าแอตทริบิวต์ของกิจกรรมรูทจะมีผลกับกิจกรรมทั้งหมดภายในสแต็กงาน เช่น หากกิจกรรมรูทมี android:resizeableActivity="true" กิจกรรมทั้งหมดในสแต็กงานจะปรับขนาดได้ ในอุปกรณ์ขนาดใหญ่บางเครื่อง เช่น Chromebook แอปอาจทำงานในหน้าต่างที่ปรับขนาดได้แม้ว่าคุณจะระบุ android:resizeableActivity="false" หากการเปลี่ยนแปลงนี้ทำให้แอปใช้งานไม่ได้ คุณสามารถใช้ตัวกรองใน Google Play เพื่อจำกัดความพร้อมให้บริการของแอปในอุปกรณ์ดังกล่าว

Android 12 (API ระดับ 31) จะใช้โหมดหลายหน้าต่างโดยค่าเริ่มต้น ในหน้าจอขนาดใหญ่ (คลาสขนาดหน้าต่างปานกลางหรือขยาย) แอปทั้งหมดจะทำงานในโหมดหลายหน้าต่าง โดยไม่คำนึงถึงการกำหนดค่าแอป ในหน้าจอขนาดเล็ก ระบบจะตรวจสอบการตั้งค่าminWidth minHeight และ resizeableActivity ของกิจกรรมเพื่อพิจารณาว่ากิจกรรมจะเรียกใช้ในโหมดหลายหน้าต่างได้หรือไม่

resizeableActivity

ตั้งค่าแอตทริบิวต์นี้ในองค์ประกอบ <activity> หรือ <application> ของไฟล์ Manifest เพื่อเปิดหรือปิดใช้โหมดหลายหน้าต่างสำหรับ API ระดับ 30 และต่ำกว่า

<application
  android:name=".MyActivity"
  android:resizeableActivity=["true" | "false"] />;

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

หากแอปกำหนดเป้าหมายเป็น API ระดับ 24 ขึ้นไป แต่คุณไม่ได้ระบุค่าสำหรับ แอตทริบิวต์นี้ ค่าเริ่มต้นของแอตทริบิวต์จะเป็นจริง

หากแอปกำหนดเป้าหมายเป็น API ระดับ 31 ขึ้นไป แอตทริบิวต์นี้จะทำงานแตกต่างกันใน หน้าจอขนาดเล็กและขนาดใหญ่ ดังนี้

  • หน้าจอขนาดใหญ่ (คลาสขนาดหน้าต่างปานกลางหรือขยาย): แอปทั้งหมด รองรับโหมดหลายหน้าต่าง แอตทริบิวต์จะระบุว่ากิจกรรมเปลี่ยนขนาดได้หรือไม่ หาก resizeableActivity="false" ระบบจะเปลี่ยนแอปเป็น โหมดความเข้ากันได้เมื่อจำเป็นเพื่อให้เป็นไปตามขนาดการแสดงผล
  • หน้าจอขนาดเล็ก (คลาสขนาดหน้าต่างกะทัดรัด): หาก resizeableActivity="true"และความกว้างและความสูงขั้นต่ำของกิจกรรม เป็นไปตามข้อกำหนดของโหมดหลายหน้าต่าง กิจกรรมจะรองรับโหมดหลายหน้าต่าง หากเป็น resizeableActivity="false" กิจกรรมจะไม่รองรับ โหมดหลายหน้าต่างไม่ว่าความกว้างและความสูงขั้นต่ำของกิจกรรมจะเป็นเท่าใดก็ตาม

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

หากคุณกำลังสร้างเกม โปรดดูการวางแนวแอป สัดส่วนการแสดงผล และ การปรับขนาดได้เพื่อดูวิธียกเว้นเกมของคุณจากการเปลี่ยนแปลงใน Android 16 (API ระดับ 36)

supportsPictureInPicture

ตั้งค่าแอตทริบิวต์นี้ในโหนด <activity> ของไฟล์ Manifest เพื่อระบุว่ากิจกรรมรองรับโหมดภาพซ้อนภาพหรือไม่

<activity
  android:name=".MyActivity"
  android:supportsPictureInPicture=["true" | "false"] />

configChanges

หากต้องการจัดการการเปลี่ยนแปลงการกำหนดค่าหลายหน้าต่างด้วยตนเอง เช่น เมื่อผู้ใช้ ปรับขนาดหน้าต่าง ให้เพิ่มแอตทริบิวต์ android:configChanges ลงในโหนด <activity> ของไฟล์ Manifest ของแอปโดยมีค่าต่อไปนี้อย่างน้อย

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize
      | screenLayout | orientation" />

หลังจากเพิ่ม android:configChanges แล้ว กิจกรรมและ Fragment จะได้รับการเรียกกลับไปยัง onConfigurationChanged() แทนที่จะถูกทำลายและสร้างใหม่ จากนั้นคุณจะอัปเดตมุมมอง โหลดทรัพยากรซ้ำ และ ดำเนินการอื่นๆ ได้ด้วยตนเองตามต้องการ

<layout>

ใน Android 7.0 (API ระดับ 24) ขึ้นไป องค์ประกอบไฟล์ Manifest ของ <layout> รองรับแอตทริบิวต์หลายรายการที่มีผลต่อลักษณะการทำงานของกิจกรรมในโหมดหลายหน้าต่าง

  • android:defaultHeight, android:defaultWidth: ความสูงและความกว้างเริ่มต้นของ กิจกรรมเมื่อเปิดในโหมดการจัดหน้าต่างบนเดสก์ท็อป

  • android:gravity: ตำแหน่งเริ่มต้นของกิจกรรมเมื่อเปิดตัวใน โหมดการจัดหน้าต่างบนเดสก์ท็อป ดูค่าที่เหมาะสมได้ในคลาส Gravity

  • android:minHeight, android:minWidth: ความสูงขั้นต่ำและความกว้างขั้นต่ำ สำหรับกิจกรรมในโหมดทั้งแบบแยกหน้าจอและแบบหน้าต่างเดสก์ท็อป หากผู้ใช้เลื่อนเส้นแบ่งในโหมดแยกหน้าจอเพื่อลดขนาดกิจกรรมให้เล็กกว่าขนาดขั้นต่ำที่ระบุ ระบบจะครอบตัดกิจกรรมให้มีขนาดตามที่ผู้ใช้ขอ

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

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end|..."
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

โหมดหลายหน้าต่างที่รันไทม์

ตั้งแต่ Android 7.0 เป็นต้นไป ระบบมีฟังก์ชันการทำงานที่รองรับแอปที่ เรียกใช้ในโหมดหลายหน้าต่างได้

ฟีเจอร์ที่ปิดใช้ในโหมดหลายหน้าต่าง

ในโหมดหลายหน้าต่าง Android อาจปิดใช้หรือละเว้นฟีเจอร์ที่ไม่เกี่ยวข้อง กับกิจกรรมที่แชร์หน้าจออุปกรณ์กับกิจกรรมหรือแอปอื่นๆ

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

ระบบจะไม่สนใจการเปลี่ยนแปลงแอตทริบิวต์ android:screenOrientation

การค้นหาและการเรียกกลับในโหมดหลายหน้าต่าง

คลาส Activity มีเมธอดต่อไปนี้เพื่อรองรับโหมดหลายหน้าต่าง

  • isInMultiWindowMode(): ระบุว่ากิจกรรมอยู่ใน โหมดหลายหน้าต่างหรือไม่

  • isInPictureInPictureMode(): ระบุว่ากิจกรรมอยู่ในโหมด การแสดงภาพซ้อนภาพหรือไม่

  • onMultiWindowModeChanged(): ระบบจะเรียกใช้เมธอดนี้ทุกครั้งที่กิจกรรมเข้าหรือออกจากโหมดหลายหน้าต่าง ระบบจะส่งค่าเป็น true หากกิจกรรมเข้าสู่โหมดหลายหน้าต่าง หรือ false หากกิจกรรมออกจากโหมดหลายหน้าต่าง

  • onPictureInPictureModeChanged(): ระบบจะเรียกใช้เมธอดนี้ทุกครั้งที่ กิจกรรมเข้าหรือออกจากโหมดการแสดงภาพซ้อนภาพ ระบบจะส่งค่าเป็นจริงไปยังเมธอดหากกิจกรรมเข้าสู่โหมดภาพซ้อนภาพ หรือส่งค่าเป็นเท็จหากกิจกรรมออกจากโหมดภาพซ้อนภาพ

คลาส Fragment จะแสดงเวอร์ชันของเมธอดเหล่านี้หลายรายการ เช่น Fragment.onMultiWindowModeChanged()

โหมดการแสดงภาพซ้อนภาพ

หากต้องการใส่กิจกรรมในโหมดการแสดงภาพซ้อนภาพ ให้เรียกใช้ enterPictureInPictureMode() วิธีนี้จะไม่มีผลหากอุปกรณ์ไม่รองรับโหมดการแสดงภาพซ้อนภาพ ดูข้อมูลเพิ่มเติมได้ที่เพิ่มวิดีโอโดยใช้การแสดงภาพซ้อนภาพ (PIP)

กิจกรรมใหม่ในโหมดหลายหน้าต่าง

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

หากอุปกรณ์อยู่ในโหมดการแสดงหน้าต่างบนเดสก์ท็อปและคุณกำลังเปิดใช้งานกิจกรรมใหม่ คุณสามารถระบุขนาดและตำแหน่งบนหน้าจอของกิจกรรมใหม่ได้โดยการเรียกใช้ ActivityOptions.setLaunchBounds() เมธอดนี้จะไม่มีผลหากอุปกรณ์ไม่ได้อยู่ในโหมดหลายหน้าต่าง

ใน API ระดับ 30 และต่ำกว่า หากคุณเปิดใช้กิจกรรมภายในสแต็กงาน กิจกรรมจะแทนที่กิจกรรมบนหน้าจอและรับค่าพร็อพเพอร์ตี้แบบหลายหน้าต่างทั้งหมด หากต้องการเปิดกิจกรรมใหม่เป็นหน้าต่างแยกต่างหากใน โหมดหลายหน้าต่าง คุณต้องเปิดกิจกรรมในสแต็กงานใหม่

Android 12 (API ระดับ 31) ช่วยให้แอปแยกหน้าต่างงานของแอปพลิเคชัน ระหว่างกิจกรรมหลายรายการได้ คุณกำหนดวิธีที่แอปแสดงกิจกรรมต่างๆ ไม่ว่าจะเป็นแบบเต็มหน้าจอ แบบเคียงข้างกัน หรือแบบซ้อนกันได้โดยการสร้างไฟล์กำหนดค่า XML หรือทำการเรียก API ของ Jetpack WindowManager

ลากและวาง

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

หลายอินสแตนซ์

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

Android 12 (API ระดับ 31) ขึ้นไปช่วยให้คุณเปิด 2 อินสแตนซ์ของ กิจกรรมแบบเคียงข้างกันในหน้าต่างงานเดียวกันในการฝังกิจกรรมได้

หากต้องการอนุญาตให้ผู้ใช้เริ่มอินสแตนซ์อื่นของแอปพลิเคชันจาก ตัวเปิดแอปพลิเคชันหรือแถบงาน ให้ตั้งค่า android:resizeableActivity="true" ในไฟล์ Manifest ของกิจกรรมตัวเรียกใช้ และอย่าใช้โหมดการเปิดตัวที่ ป้องกันไม่ให้มีหลายอินสแตนซ์ เช่น singleInstancePerTask กิจกรรมสามารถ สร้างอินสแตนซ์ได้หลายครั้งในงานต่างๆ เมื่อตั้งค่า FLAG_ACTIVITY_MULTIPLE_TASK หรือ FLAG_ACTIVITY_NEW_DOCUMENT

ใน Android 15 (API ระดับ 35) ขึ้นไป PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI จะช่วยให้คุณประกาศการรองรับ สำหรับหลายอินสแตนซ์ได้ พร็อพเพอร์ตี้เป็นสัญญาณที่ชัดเจนสำหรับ UI ของระบบในการ แสดงตัวควบคุมต่อผู้ใช้เพื่อสร้างอินสแตนซ์ของแอปหลายรายการ พร็อพเพอร์ตี้ ไม่ขึ้นอยู่กับโหมดการเปิด แต่ควรใช้เฉพาะเมื่อโหมดการเปิด สำหรับกิจกรรมหรือแอปพลิเคชันเข้ากันได้กับพร็อพเพอร์ตี้ เช่น เมื่อโหมดการเปิดไม่ใช่ singleInstance

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

การยืนยันโหมดหลายหน้าต่าง

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

ทดสอบอุปกรณ์

อุปกรณ์ที่ใช้ Android 7.0 (API ระดับ 24) ขึ้นไปรองรับโหมดหลายหน้าต่าง

API ระดับ 23 หรือต่ำกว่า

เมื่อผู้ใช้พยายามใช้แอปในโหมดหลายหน้าต่าง ระบบจะบังคับ ปรับขนาดแอป เว้นแต่แอปจะประกาศการวางแนวคงที่

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

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

API ระดับ 24 ถึง 30

หากแอปกำหนดเป้าหมายเป็น API ระดับ 24-30 และไม่ได้ปิดใช้การรองรับหลายหน้าต่าง ให้ตรวจสอบลักษณะการทำงานต่อไปนี้ในโหมดการแสดงผลแบบแยกหน้าจอและโหมดการแสดงผลแบบเดสก์ท็อป

  • เปิดแอปแบบเต็มหน้าจอ แล้วเปลี่ยนเป็นโหมดหลายหน้าต่างโดย กดปุ่มล่าสุดค้างไว้ ตรวจสอบว่าแอปเปลี่ยนอย่างถูกต้อง

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

  • ปรับขนาดแอปในโหมดแยกหน้าจอโดยลากเส้นแบ่งหน้าจอ ยืนยัน ว่าแอปปรับขนาดได้โดยไม่ขัดข้องและองค์ประกอบ UI ที่จำเป็น มองเห็นได้

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

  • ในการทดสอบทั้งหมด ให้ตรวจสอบว่าประสิทธิภาพของแอปอยู่ในระดับที่ยอมรับได้ เช่น ตรวจสอบว่าไม่มีความล่าช้ามากเกินไปในการอัปเดต UI หลังจากปรับขนาดแอป

API ระดับ 31 ขึ้นไป

หากแอปกำหนดเป้าหมายเป็น API ระดับ 31 ขึ้นไป และความกว้างขั้นต่ำ และความสูงขั้นต่ำของกิจกรรมหลักน้อยกว่าหรือเท่ากับขนาดที่เกี่ยวข้องของ พื้นที่แสดงผลที่ใช้ได้ ให้ตรวจสอบลักษณะการทำงานทั้งหมดที่ระบุไว้สำหรับ API ระดับ 24 ถึง 30

รายการตรวจสอบการทดสอบ

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

  • เข้าและออกจากโหมดหลายหน้าต่าง

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

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

  • ดำเนินการปรับขนาดหลายครั้งอย่างรวดเร็ว ตรวจสอบว่าแอป ไม่ขัดข้องหรือมีหน่วยความจำรั่ว Memory Profiler ของ Android Studio จะให้ข้อมูลเกี่ยวกับการใช้งานหน่วยความจำของแอป (ดูตรวจสอบการใช้งานหน่วยความจำของแอปด้วย Memory Profiler)

  • ใช้แอปตามปกติในการกำหนดค่าหน้าต่างต่างๆ และ ตรวจสอบว่าแอปทำงานอย่างถูกต้อง ตรวจสอบว่าข้อความอ่านได้และองค์ประกอบ UI ไม่เล็กเกินไปจนโต้ตอบไม่ได้

ปิดใช้การรองรับฟีเจอร์หลายหน้าต่างแล้ว

ใน API ระดับ 24-30 หากปิดใช้การรองรับหลายหน้าต่างโดยการตั้งค่า android:resizeableActivity="false" คุณควรเปิดแอปในอุปกรณ์ที่ใช้ Android 7.0-11 แล้วลองใส่แอปในโหมดแบ่งหน้าจอและ โหมดหน้าต่างเดสก์ท็อป ตรวจสอบว่าเมื่อคุณทำเช่นนั้น แอปจะยังคงอยู่ใน โหมดเต็มหน้าจอ

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับการรองรับหลายหน้าต่างใน Android ได้ที่