หากต้องการปรับแต่งวิธีเรียกใช้ภาพเคลื่อนไหวการเปลี่ยนองค์ประกอบที่แชร์ ให้ทำดังนี้ ที่ใช้เปลี่ยนวิธีเปลี่ยนองค์ประกอบที่แชร์
ข้อกำหนดเฉพาะของแอนิเมชัน
หากต้องการเปลี่ยนข้อกำหนดของภาพเคลื่อนไหวที่ใช้สำหรับการเคลื่อนไหวของขนาดและตำแหน่ง ให้ระบุพารามิเตอร์ 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
โหมดปรับขนาด
เมื่อสร้างภาพเคลื่อนไหวระหว่างขอบเขตที่แชร์ 2 รายการ คุณสามารถตั้งค่าพารามิเตอร์ resizeMode
เป็น RemeasureToBounds
หรือ ScaleToBounds
พารามิเตอร์นี้จะกำหนดลักษณะการเปลี่ยนองค์ประกอบที่แชร์ระหว่าง 2 สถานะ ScaleToBounds
ก่อน
วัดเลย์เอาต์ย่อยด้วยข้อจำกัด Lookahead (หรือเป้าหมาย) จากนั้นระบบจะปรับขนาดเลย์เอาต์ที่เสถียรของรายการย่อยให้พอดีกับขอบเขตที่แชร์
ScaleToBounds
อาจหมายถึง "ระดับกราฟิก" ระหว่างรัฐเหล่านี้
ส่วน RemeasureToBounds
จะวัดและจัดเลย์เอาต์ย่อยของ sharedBounds
ใหม่อีกครั้งโดยใช้ข้อจำกัดแบบคงที่ที่เคลื่อนไหวตามขนาดเป้าหมาย การวัดผลอีกครั้งจะทริกเกอร์โดยการเปลี่ยนแปลงขนาดขอบเขต ซึ่งอาจเกิดขึ้นทุกเฟรม
สำหรับคอมโพสิเบิล Text
เราขอแนะนำให้ใช้ ScaleToBounds
เนื่องจากจะหลีกเลี่ยงการจัดเรียงใหม่และการจัดเรียงข้อความใหม่ในบรรทัดต่างๆ สำหรับขอบเขตที่มีสัดส่วนการแสดงผลต่างกัน และหากต้องการให้องค์ประกอบที่แชร์ 2 รายการต่อเนื่องกันแบบราบรื่น เราขอแนะนำให้ใช้ RemeasureToBounds
ดูความแตกต่างระหว่างโหมดการปรับขนาด 2 โหมดได้จากตัวอย่างต่อไปนี้
|
|
---|---|
ข้ามไปยังเลย์เอาต์สุดท้าย
โดยค่าเริ่มต้น เมื่อเปลี่ยนระหว่างเลย์เอาต์ 2 รูปแบบ ขนาดเลย์เอาต์จะเคลื่อนไหวระหว่างสถานะเริ่มต้นและสถานะสุดท้าย นี่อาจเป็นพฤติกรรมที่ไม่พึงประสงค์เมื่อ การทำให้เนื้อหา เช่น ข้อความเคลื่อนไหว
ตัวอย่างต่อไปนี้แสดงข้อความอธิบาย "Lorem Ipsum" ที่ปรากฏบนหน้าจอ 2 วิธี ตัวอย่างแรก ข้อความจะจัดเรียงใหม่เมื่อเข้าสู่คอนเทนเนอร์ที่ขยายขนาดขึ้น ส่วนตัวอย่างที่ 2 ข้อความจะไม่จัดเรียงใหม่เมื่อขยายขนาด การเพิ่ม Modifier.skipToLookaheadSize()
จะป้องกันไม่ให้เกิดการจัดเรียงใหม่
เมื่อธุรกิจเติบโตขึ้น
ไม่มี Modifier.skipToLookahead() - สังเกตการเรียงบรรทัดข้อความ "Lorem Ipsum" ใหม่ |
Modifier.skipToLookahead() - สังเกตว่าข้อความ "Lorem Ipsum" ยังคงอยู่ในสถานะสุดท้ายที่จุดเริ่มต้นของภาพเคลื่อนไหว |
---|---|
คลิปและการวางซ้อน
แนวคิดสําคัญในการสร้างองค์ประกอบที่แชร์ใน Compose คือการเรนเดอร์คอมโพสิเบิลจะยกระดับเป็นเลเยอร์วางซ้อนเมื่อเริ่มการเปลี่ยนเพื่อจับคู่กับคอมโพสิเบิลปลายทาง เพื่อให้คอมโพสิเบิลต่างๆ แชร์องค์ประกอบได้ ข้อดีคือช่วยหลีกหนี ขอบเขตระดับบนสุดและการเปลี่ยนรูปแบบเลเยอร์ (เช่น อัลฟาและสเกล)
โดยจะแสดงผลทับองค์ประกอบ 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 อื่นก่อนการเปลี่ยนแปลง ในกรณีเช่นนี้ ให้ใช้ renderInSharedTransitionScopeOverlay().animateEnterExit()
เพื่อแสดงภาพเคลื่อนไหวของคอมโพสิเบิลออกขณะที่ทรานซิชันองค์ประกอบที่แชร์ทำงานอยู่
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
ในกรณีที่ไม่บ่อยนักที่คุณต้องการไม่ให้องค์ประกอบที่แชร์แสดงผลในการวางซ้อน คุณสามารถตั้งค่า renderInOverlayDuringTransition
ใน sharedElement()
เป็น false
แจ้งเลย์เอาต์แบบพี่น้องเกี่ยวกับการเปลี่ยนแปลงขนาดองค์ประกอบที่แชร์
โดยค่าเริ่มต้น sharedBounds()
และ sharedElement()
จะไม่แจ้งให้คอนเทนเนอร์หลักทราบถึงการเปลี่ยนแปลงขนาดเมื่อเลย์เอาต์เปลี่ยน
หากต้องการเผยแพร่การเปลี่ยนแปลงขนาดไปยังคอนเทนเนอร์หลักขณะที่เปลี่ยน ให้เปลี่ยนพารามิเตอร์ placeHolderSize
เป็น PlaceHolderSize.animatedSize
กำลังทำ
รายการดังกล่าวจึงเพิ่มขึ้นหรือหดสั้นลง รายการอื่นๆ ทั้งหมดในเลย์เอาต์จะตอบสนองต่อการเปลี่ยนแปลง
|
(สังเกตว่ารายการอื่นๆ ในรายการขยับลงเพื่อตอบสนองต่อรายการเดียวที่เพิ่มขึ้นอย่างไร) |
---|---|