หากต้องการปรับแต่งวิธีที่ภาพเคลื่อนไหวของการเปลี่ยนองค์ประกอบที่ใช้ร่วมกันทำงาน คุณสามารถใช้พารามิเตอร์ 2-3 รายการเพื่อเปลี่ยนวิธีที่องค์ประกอบที่ใช้ร่วมกันเปลี่ยนภาพ
ข้อกำหนดของภาพเคลื่อนไหว
หากต้องการเปลี่ยนข้อกำหนดภาพเคลื่อนไหวที่ใช้สำหรับการเคลื่อนไหวของขนาดและตำแหน่ง คุณสามารถ
ระบุboundsTransform
พารามิเตอร์อื่นใน Modifier.sharedElement()
ได้
ซึ่งจะระบุตำแหน่งเริ่มต้น Rect
และตำแหน่งเป้าหมาย Rect
เช่น หากต้องการให้ข้อความในตัวอย่างก่อนหน้าเคลื่อนที่ตามเส้นโค้ง
ให้ระบุพารามิเตอร์ boundsTransform
เพื่อใช้ข้อมูลจำเพาะ keyframes
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
คุณใช้ AnimationSpec
ใดก็ได้ ตัวอย่างนี้ใช้ข้อกำหนด keyframes
boundsTransform
พารามิเตอร์โหมดปรับขนาด
เมื่อเคลื่อนไหวระหว่างขอบเขตที่แชร์ 2 รายการ คุณสามารถตั้งค่าพารามิเตอร์ resizeMode
เป็น RemeasureToBounds
หรือ ScaleToBounds
ได้ พารามิเตอร์นี้จะกำหนดวิธี
การเปลี่ยนองค์ประกอบที่แชร์ระหว่าง 2 สถานะ ScaleToBounds
จะวัดเลย์เอาต์ย่อยด้วยข้อจำกัดในการมองล่วงหน้า (หรือเป้าหมาย) ก่อน จากนั้นระบบจะปรับขนาดเลย์เอาต์ที่เสถียรของ
บุตรหลานให้พอดีกับขอบเขตที่แชร์
ScaleToBounds
สามารถมองได้ว่าเป็น "มาตราส่วนกราฟิก" ระหว่างสถานะ
ในทางตรงกันข้าม RemeasureToBounds
จะวัดและจัดเลย์เอาต์ใหม่สำหรับเลย์เอาต์ย่อยของ
sharedBounds
โดยมีข้อจำกัดคงที่แบบเคลื่อนไหวตามขนาดเป้าหมาย
การวัดซ้ำจะทริกเกอร์โดยการเปลี่ยนแปลงขนาดขอบเขต ซึ่งอาจเกิดขึ้น
ทุกเฟรม
สำหรับ Composable ของ Text
เราขอแนะนำให้ใช้ ScaleToBounds
เนื่องจากจะช่วยหลีกเลี่ยงการจัดวางใหม่
และการเปลี่ยนบรรทัดข้อความ RemeasureToBounds
ขอแนะนำ
สำหรับขอบเขตที่มีสัดส่วนภาพต่างกัน และหากคุณต้องการให้องค์ประกอบที่แชร์ 2 รายการมีความต่อเนื่องที่ราบรื่น
ความแตกต่างระหว่างโหมดปรับขนาดทั้ง 2 โหมดจะเห็นได้ในตัวอย่างต่อไปนี้
|
|
---|---|
ข้ามไปยังเลย์เอาต์สุดท้าย
โดยค่าเริ่มต้น เมื่อเปลี่ยนระหว่างเลย์เอาต์ 2 แบบ ขนาดเลย์เอาต์จะเคลื่อนไหว ระหว่างสถานะเริ่มต้นและสถานะสุดท้าย ซึ่งอาจเป็นลักษณะการทำงานที่ไม่พึงประสงค์เมื่อ สร้างภาพเคลื่อนไหวเนื้อหา เช่น ข้อความ
ตัวอย่างต่อไปนี้แสดงข้อความคำอธิบาย "Lorem Ipsum" ที่ปรากฏบนหน้าจอใน 2 วิธีที่แตกต่างกัน ในตัวอย่างแรก ข้อความจะปรับให้พอดีกับคอนเทนเนอร์เมื่อคอนเทนเนอร์มีขนาดใหญ่ขึ้น
ในตัวอย่างที่ 2 ข้อความจะไม่
จัดข้อความใหม่เมื่อขยาย การเพิ่ม Modifier.skipToLookaheadSize()
จะป้องกันการปรับข้อความใหม่
เมื่อข้อความยาวขึ้น
ไม่มี |
|
---|---|
คลิปและภาพซ้อนทับ
เพื่อให้องค์ประกอบที่แชร์ใช้ร่วมกันระหว่าง Composable ต่างๆ ได้ การแสดงผลของ Composable จะได้รับการยกระดับเป็นเลเยอร์ซ้อนทับเมื่อ เริ่มการเปลี่ยนไปยังองค์ประกอบที่ตรงกันในปลายทาง ซึ่งจะทำให้ หลุดออกจากขอบเขตขององค์ประกอบหลักและการแปลงเลเยอร์ (เช่น อัลฟ่าและสเกล)
โดยจะแสดงทับองค์ประกอบ UI อื่นๆ ที่ไม่ได้แชร์ เมื่อการเปลี่ยนผ่าน
เสร็จสมบูรณ์แล้ว ระบบจะนำองค์ประกอบออกจากภาพซ้อนทับไปยังDrawScope
ขององค์ประกอบนั้นเอง
หากต้องการตัดองค์ประกอบที่ใช้ร่วมกันให้เป็นรูปร่าง ให้ใช้ฟังก์ชัน Modifier.clip()
มาตรฐาน วางไว้หลัง sharedElement()
ดังนี้
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
หากต้องการให้มั่นใจว่าองค์ประกอบที่แชร์จะไม่แสดงนอกคอนเทนเนอร์หลัก คุณสามารถตั้งค่า clipInOverlayDuringTransition
ใน sharedElement()
ได้ โดยค่าเริ่มต้น สำหรับขอบเขตที่แชร์แบบซ้อน clipInOverlayDuringTransition
จะใช้เส้นทางคลิปจาก sharedBounds()
ระดับบน
หากต้องการรองรับการคงองค์ประกอบ UI บางอย่าง เช่น แถบด้านล่างหรือปุ่มการดำเนินการแบบลอยไว้ด้านบนเสมอระหว่างการเปลี่ยนองค์ประกอบที่ใช้ร่วมกัน ให้ใช้
Modifier.renderInSharedTransitionScopeOverlay()
โดยค่าเริ่มต้น ตัวแก้ไขนี้จะเก็บเนื้อหาไว้ในภาพซ้อนทับในช่วงเวลาที่ทรานซิชันที่แชร์ทำงานอยู่
ตัวอย่างเช่น ใน Jetsnack BottomAppBar
ต้องวางไว้เหนือองค์ประกอบที่แชร์จนกว่าหน้าจอจะไม่แสดง การเพิ่มตัวแก้ไข
ลงใน Composable จะช่วยให้ Composable นั้นยังคงอยู่
ไม่มี |
ด้วย |
---|---|
คุณอาจต้องการให้ Composable ที่ไม่ได้แชร์เคลื่อนไหวออกไปและ
ยังคงอยู่เหนือ Composable อื่นๆ ก่อนการเปลี่ยน ในกรณีเช่นนี้ ให้ใช้
renderInSharedTransitionScopeOverlay().animateEnterExit()
เพื่อเคลื่อนไหว
Composables ออกขณะที่การเปลี่ยนภาพองค์ประกอบที่แชร์ทำงานอยู่
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
ในกรณีที่ไม่ได้เกิดขึ้นบ่อยนัก หากคุณไม่ต้องการให้องค์ประกอบที่แชร์แสดงใน
ภาพซ้อนทับ คุณสามารถตั้งค่า renderInOverlayDuringTransition
ใน sharedElement()
เป็น false ได้
แจ้งเลย์เอาต์ที่เกี่ยวข้องเกี่ยวกับการเปลี่ยนแปลงขนาดขององค์ประกอบที่แชร์
โดยค่าเริ่มต้น sharedBounds()
และ sharedElement()
จะไม่แจ้งให้คอนเทนเนอร์ระดับบนสุดทราบถึงการเปลี่ยนแปลงขนาดใดๆ เมื่อเลย์เอาต์เปลี่ยน
หากต้องการเผยแพร่การเปลี่ยนแปลงขนาดไปยังคอนเทนเนอร์ระดับบนสุดเมื่อมีการเปลี่ยน
ให้เปลี่ยนพารามิเตอร์ placeHolderSize
เป็น PlaceHolderSize.animatedSize
การทำเช่นนี้จะทำให้ไอเทมขยายหรือหดตัว รายการอื่นๆ ทั้งหมดในเลย์เอาต์จะตอบสนองต่อ
การเปลี่ยนแปลง
|
(สังเกตว่ารายการอื่นๆ ในลิสต์จะเลื่อนลงเมื่อมีรายการหนึ่งเพิ่มขึ้น) |
---|---|