แสดงเนื้อหาแบบไร้ขอบในแอป

ลองใช้วิธีการเขียน
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีการทำงานแบบไร้ขอบในการเขียน

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

แอปจำนวนมากมีแถบแอปด้านบน แถบแอปด้านบนควรยืดไปถึงขอบด้านบนของ และแสดงขึ้นด้านหลังแถบสถานะ (ไม่บังคับ) แถบแอปด้านบนสามารถ ย่อจนเท่ากับความสูงของแถบสถานะเมื่อเนื้อหาเลื่อน

แอปจำนวนมากมีแถบแอปด้านล่างหรือแถบนำทางด้านล่างด้วย แถบเหล่านี้ควร ยืดไปที่ขอบด้านล่างของหน้าจอและแสดงด้านหลังของการนำทาง แถบ มิเช่นนั้น แอปควรแสดงเนื้อหาที่เลื่อนได้หลังแถบนำทาง

รูปที่ 1 แถบระบบในเลย์เอาต์แบบไร้ขอบ

เมื่อคุณใช้เลย์เอาต์แบบขอบถึงขอบในแอป โปรดดำเนินการดังนี้ใน ใจ:

  1. เปิดใช้การแสดงผลแบบไร้ขอบ
  2. จัดการกับภาพที่ทับซ้อนกัน
  3. ลองแสดงขอบด้านหลังแถบระบบ
ตัวอย่างภาพด้านหลังแถบสถานะ
รูปที่ 2 ตัวอย่างภาพด้านหลัง แถบสถานะ

เปิดใช้การแสดงผลแบบไร้ขอบ

หากแอปกำหนดเป้าหมายเป็น SDK 35 ขึ้นไป ระบบจะเปิดใช้แบบไร้ขอบโดยอัตโนมัติสำหรับ อุปกรณ์ Android 15 ขึ้นไป

หากต้องการเปิดใช้ EDGE-to-EDGE ใน Android เวอร์ชันก่อนหน้า ให้ทำดังนี้

  1. เพิ่มการอ้างอิงลงใน androidx.activity ในไลบรารี build.gradle ของแอปหรือโมดูล

    Kotlin

    dependencies {
        val activity_version = activity_version
        // Java language implementation
        implementation("androidx.activity:activity:$activity_version")
        // Kotlin
        implementation("androidx.activity:activity-ktx:$activity_version")
    }
    

    ดึงดูด

    dependencies {
        def activity_version = activity_version
        // Java language implementation
        implementation 'androidx.activity:activity:$activity_version'
        // Kotlin
        implementation 'androidx.activity:activity-ktx:$activity_version'
    }
    
  2. นำเข้าenableEdgeToEdge ฟังก์ชันของส่วนขยายลงในแอปของคุณ

เปิดใช้โฆษณาแบบไร้ขอบด้วยตนเองด้วยการเรียกใช้ enableEdgeToEdge ใน onCreate ของ Activity ควรเรียกใช้ก่อน setContentView

Kotlin

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

Java

     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
       EdgeToEdge.enable(this);
       super.onCreate(savedInstanceState);
       ...
     }
   

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

ฟังก์ชัน enableEdgeToEdge() จะประกาศโดยอัตโนมัติว่าแอปควร จัดวางแบบขอบต่อขอบ และปรับสีของแถบระบบ

วิธีเปิดใช้การแสดงผลแบบไร้ขอบในแอปโดยไม่ต้องใช้ ฟังก์ชัน enableEdgeToEdge() โปรดดู ตั้งค่าการแสดงผลแบบไร้ขอบด้วยตนเอง

จัดการการซ้อนทับโดยใช้ส่วนแทรก

มุมมองของแอปบางส่วนอาจวาดอยู่หลังแถบระบบ ดังที่แสดงในรูป 3.

คุณสามารถจัดการการซ้อนทับได้โดยการโต้ตอบกับส่วนต่างๆ ซึ่งระบุถึงส่วนของ หน้าจอตัดกับ UI ของระบบ เช่น แถบนำทาง หรือสถานะ แถบ การทับซ้อนอาจหมายถึงการแสดงที่ด้านบนเนื้อหา แต่ยังสามารถบอก เกี่ยวกับท่าทางสัมผัสของระบบ

ประเภทของชิ้นส่วนที่ใช้กับการแสดงแอปของคุณแบบขอบต่อขอบ ได้แก่

  • ส่วนแทรกของแถบระบบ: เหมาะสำหรับมุมมองที่แตะได้และต้องไม่ ถูกแถบระบบบดบังการมองเห็น

  • ส่วนที่เกี่ยวกับหน้าจอรอยบาก: สำหรับพื้นที่ที่อาจมีหน้าจอรอยบาก เนื่องจากรูปทรงของอุปกรณ์

  • ส่วนท่าทางสัมผัสของระบบ: สำหรับพื้นที่ที่มีการนำทางด้วยท่าทางสัมผัสที่ระบบใช้ ที่มีความสำคัญเหนือแอปของคุณ

ส่วนของแถบระบบ

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

ตัวอย่างเช่น การทำงานแบบลอย button (FAB) ในรูปที่ 3 บางส่วน ถูกบดบังด้วยแถบนำทาง

วันที่ ตัวอย่างของการใช้งานแบบไร้ขอบ แต่แถบนำทางกลับบดบัง FAB
รูปที่ 3 แถบนำทางซ้อนทับกับ FAB ใน แบบไร้ขอบ

เพื่อหลีกเลี่ยงภาพที่ทับซ้อนกันแบบนี้ในโหมดท่าทางสัมผัสหรือโหมดปุ่ม คุณสามารถ สามารถเพิ่มขอบของมุมมองโดยใช้ getInsets(int) กับ WindowInsetsCompat.Type.systemBars()

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีใช้งานส่วนในแถบระบบ

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets ->
  val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
  // Apply the insets as a margin to the view. This solution sets
  // only the bottom, left, and right dimensions, but you can apply whichever
  // insets are appropriate to your layout. You can also update the view padding
  // if that's more appropriate.
  v.updateLayoutParams<MarginLayoutParams> {
      leftMargin = insets.left,
      bottomMargin = insets.bottom,
      rightMargin = insets.right,
  }

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> {
  Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
  // Apply the insets as a margin to the view. This solution sets only the
  // bottom, left, and right dimensions, but you can apply whichever insets are
  // appropriate to your layout. You can also update the view padding if that's
  // more appropriate.
  MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
  mlp.leftMargin = insets.left;
  mlp.bottomMargin = insets.bottom;
  mlp.rightMargin = insets.right;
  v.setLayoutParams(mlp);

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

ถ้าคุณใช้โซลูชันนี้กับตัวอย่างที่แสดงในรูปที่ 3 ผลลัพธ์จะไม่ใช่ ภาพที่ทับซ้อนกันในโหมดปุ่มดังที่แสดงในรูปที่ 4

วันที่ แถบนำทางโปร่งแสงไม่บดบัง FAB
รูปที่ 4 การแก้ไขภาพที่ทับซ้อนกันในปุ่ม

เช่นเดียวกันกับโหมดการนำทางด้วยท่าทางสัมผัสดังที่แสดงในรูปที่ 5

วันที่ แบบไร้ขอบด้วยการนำทางด้วยท่าทางสัมผัส
รูปที่ 5 การแก้ไขภาพที่ทับซ้อนกันในท่าทางสัมผัส โหมดการนำทาง

ส่วนแสดงคัตเอาต์

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

ตัวอย่างเช่น หน้าจอแอปหลายๆ หน้าจอจะแสดงรายการต่างๆ อย่าปิดบังรายการ ด้วยหน้าจอรอยบากหรือแถบระบบ

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets ->
  val bars = insets.getInsets(
    WindowInsetsCompat.Type.systemBars()
      or WindowInsetsCompat.Type.displayCutout()
  )
  v.updatePadding(
    left = bars.left,
    top = bars.top,
    right = bars.right,
    bottom = bars.bottom,
  )
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> {
  WindowInsetsCompat bars = insets.getInsets(
    WindowInsetsCompat.Type.systemBars()
    | WindowInsetsCompat.Type.displayCutout()
  );
  v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
  return WindowInsetsCompat.CONSUMED;
});

ระบุค่าของ WindowInsetsCompat โดยใช้ตรรกะ หรือ ของ แถบระบบและประเภทของหน้าจอรอยบาก

ตั้งค่า clipToPadding เป็น RecyclerView เพื่อให้ระยะห่างจากขอบเลื่อนด้วย รายการ ซึ่งจะทำให้รายการอยู่หลังแถบระบบเมื่อผู้ใช้ การเลื่อน ดังที่ปรากฏในตัวอย่างต่อไปนี้

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

การตั้งค่าท่าทางสัมผัสของระบบ

การตั้งค่าท่าทางสัมผัสของระบบจะแสดงพื้นที่ของหน้าต่างที่มีท่าทางสัมผัสของระบบ สำคัญเหนือแอปของคุณ พื้นที่เหล่านี้จะแสดงเป็นสีส้มในรูปที่ 6:

วันที่ ตัวอย่างส่วนแสดงท่าทางสัมผัสของระบบ
รูปที่ 6 ใส่ท่าทางสัมผัสของระบบแล้ว

คุณหลีกเลี่ยงการทับซ้อนกันของส่วนท่าทางสัมผัสของระบบได้เช่นเดียวกับส่วนที่เป็นแถบระบบ โดยใช้ getInsets(int) กับ WindowInsetsCompat.Type.systemGestures()

ใช้ส่วนเหล่านี้เพื่อย้ายหรือเลื่อนมุมมองที่ปัดได้ออกจากขอบ การใช้งานทั่วไป เช่น Bottom Sheet การปัดในเกม และภาพหมุนที่ใช้การ ViewPager2

ใน Android 10 ขึ้นไป องค์ประกอบท่าทางสัมผัสของระบบจะมีกรอบด้านล่างสำหรับ ท่าทางสัมผัสที่หน้าแรก และการแทรกด้านซ้ายและขวาสำหรับท่าทางสัมผัสการย้อนกลับ

วันที่ ตัวอย่างการวัดค่าท่าทางสัมผัสของระบบ
รูปที่ 7 การวัดการตั้งค่าท่าทางสัมผัสของระบบ

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีใช้การตั้งค่าท่าทางสัมผัสของระบบ

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.updatePadding(insets.left, insets.top, insets.right, insets.bottom)

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
    Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures());
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.setPadding(insets.left, insets.top, insets.right, insets.bottom);

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

คอมโพเนนต์เนื้อหา

คอมโพเนนต์ Material ของ Android ที่อิงตามการดูหลายรายการ (com.google.android.material){:.external} จัดการสิ่งที่ประกอบโดยอัตโนมัติ ซึ่งรวมถึง BottomAppBar BottomNavigationView, NavigationRailView และ NavigationView

อย่างไรก็ตาม AppBarLayout จะไม่จัดการกับการใส่กรอบโดยอัตโนมัติ เพิ่ม android:fitsSystemWindows="true" เพื่อจัดการส่วนบนสุดหรือใช้ setOnApplyWindowInsetsListener

อ่านวิธีจัดการการตั้งค่าด้วย Material Components ใน Compose

โหมดใหญ่พิเศษ

เนื้อหาบางอย่างเหมาะกับการรับชมแบบเต็มหน้าจอ ประสบการณ์ที่สมจริง คุณสามารถซ่อนแถบระบบและโหมดใหญ่พิเศษได้โดยใช้ WindowInsetsController และ WindowInsetsControllerCompat ไลบรารี:

Kotlin

val windowInsetsController =
      WindowCompat.getInsetsController(window, window.decorView)

// Hide the system bars.
windowInsetsController.hide(Type.systemBars())

// Show the system bars.
windowInsetsController.show(Type.systemBars())

Java

Window window = getWindow();
WindowInsetsControllerCompat windowInsetsController =
      WindowCompat.getInsetsController(window, window.getDecorView());
if (windowInsetsController == null) {
    return;
  }
// Hide the system bars.
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());

// Show the system bars.
windowInsetsController.show(WindowInsetsCompat.Type.systemBars());

โปรดดูหัวข้อซ่อนแถบระบบสำหรับโหมดใหญ่พิเศษ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้งานฟีเจอร์นี้

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับWindowInsetsท่าทางสัมผัสในข้อมูลอ้างอิงต่อไปนี้ การนำทาง และวิธีการทำงานขององค์ประกอบ