กองซ้อนแนวตั้งใน Jetpack Compose Glimmer

อุปกรณ์ XR ที่รองรับ
คำแนะนำนี้จะช่วยคุณสร้างประสบการณ์การใช้งานสำหรับอุปกรณ์ XR ประเภทต่างๆ
แว่นตา Display

ใน Jetpack Compose Glimmer นั้น VerticalStack เป็นเลย์เอาต์ที่เลื่อนได้ในแนวตั้งแบบ Lazy ซึ่งจัดเรียงรายการในลำดับสามมิติที่ซ้อนทับกันในเชิงภาพ รายการหลักจะแสดงอย่างโดดเด่นในเบื้องหน้า ขณะที่รายการต่อๆ ไปจะวางอยู่ด้านหลัง

รูปที่ 1 ตัวอย่างสแต็กบางสไตล์ใน Jetpack Compose Glimmer

ลักษณะการทำงานของการเลื่อนและการวางตำแหน่ง

เนื่องจากสแต็กจะจัดเรียงรายการในเลย์เอาต์ที่กะทัดรัดและซ้อนทับกัน จึงมี ลักษณะการทำงานบางอย่างที่แตกต่างจากคอมโพเนนต์แบบลำดับประเภทอื่นๆ เช่น รายการ

  • เมื่อผู้ใช้เลื่อนในแนวตั้ง รายการเบื้องหน้าที่ใช้งานอยู่จะเลื่อนออกจากมุมมอง ทำให้รายการที่อยู่ด้านล่างเลื่อนขึ้นมาอยู่ในตำแหน่งเบื้องหน้าที่โดดเด่น
  • รายการจะ Snap-animate โดยใช้แอนิเมชันแรงสปริงเฉพาะไปยังตำแหน่งเบื้องหน้าเสมอหลังจากที่ท่าทางของผู้ใช้สิ้นสุดลง
  • รายการจะวางตำแหน่งตามแกน Z โดยรายการที่อยู่ลึกเข้าไปในรายการจะวางอยู่ด้านหลังรายการหลัก

การจัดการโฟกัส

VerticalStack ใช้ระบบโฟกัสเฉพาะเพื่อให้แน่ใจว่ารายการเบื้องหน้าปัจจุบันจะเป็นเป้าหมายหลักสำหรับการโต้ตอบของผู้ใช้เสมอ

  • โฟกัสเริ่มต้นและการกลับเข้า: โฟกัสเริ่มต้นและการกลับเข้าของโฟกัสจะไปที่รายการบนสุดปัจจุบันของสแต็ก
  • การแจ้งเตือนโฟกัสอัตโนมัติ: เมื่อรายการเปลี่ยนไป สแต็กจะขอโฟกัส สำหรับรายการบนสุด
  • การติดตามโฟกัส: แต่ละรายการใช้ onFocusChanged เพื่อแจ้ง StackStateเกี่ยวกับสถานะโฟกัสของรายการนั้นๆ

ตัวอย่าง: สร้างสแต็กแนวตั้ง

โค้ดต่อไปนี้สร้างสแต็กแนวตั้งที่มีหลายรายการ

@Composable
fun VerticalStackSample() {
    VerticalStack(modifier = Modifier.fillMaxWidth().height(364.dp)) {
        item(key = 0) {
            Card(modifier = Modifier.fillMaxSize().itemDecoration(CardDefaults.shape)) {
                Text(
                    "Item-0",
                    style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated),
                )
            }
        }
        items(count = 10, key = { it + 1 }) { index ->
            Card(modifier = Modifier.fillMaxSize().itemDecoration(CardDefaults.shape)) {
                Text(
                    "Item-${index + 1}",
                    style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated),
                )
            }
        }
    }
}

ประเด็นสำคัญเกี่ยวกับโค้ด

  • ตั้งค่า textMotion สำหรับ LocalTextStyle ของข้อความเป็น Animated ซึ่งจะช่วยให้การแสดงข้อความราบรื่นขึ้นระหว่างการเปลี่ยนภาพเลย์เอาต์หรือการเปลี่ยนภาพการปรับขนาด เพื่อป้องกันอาร์ติแฟกต์การ Snap พิกเซล
  • กำหนดขนาดเฉพาะ 364.dp สำหรับความสูงของสแต็กแนวตั้ง กำหนดความสูงที่เฉพาะเจาะจง ใช้ตัวปรับแต่งความสูง หรือใช้ตัวปรับแต่ง fillMaxSize เสมอเพื่อกำหนดพื้นที่ภาพสำหรับการเปลี่ยนภาพการ์ด
  • VerticalStack จะจัดการขอบเขตภาพของรายการโดยใช้ตัวปรับแต่ง itemDecoration ซึ่งแตกต่างจากคอมโพเนนต์อื่นๆ ที่ใช้พารามิเตอร์รูปร่างโดยตรง ตัวอย่างนี้ส่งรูปร่างเดียวกันสำหรับ itemDecoration ของรายการเริ่มต้นกับรายการย่อยทั้งหมดเพื่อรักษาการตัดและการแสดงภาพที่สอดคล้องกัน ตัวอย่างนี้ใช้ เริ่มต้น CardDefaults.shape