หากต้องการปรับแต่งวิธีที่ภาพเคลื่อนไหวของการเปลี่ยนองค์ประกอบที่ใช้ร่วมกันทำงาน คุณสามารถใช้พารามิเตอร์ 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
การทำเช่นนี้จะทำให้ไอเทมขยายหรือหดตัว รายการอื่นๆ ทั้งหมดในเลย์เอาต์จะตอบสนองต่อ
การเปลี่ยนแปลง
|
(สังเกตว่ารายการอื่นๆ ในรายการจะเลื่อนลงเมื่อมีรายการหนึ่งเพิ่มขึ้น) |
---|---|