Nhiều API ảnh động thường chấp nhận các tham số để tuỳ chỉnh hoạt động của chúng.
Tuỳ chỉnh ảnh động bằng tham số AnimationSpec
Hầu hết các API ảnh động đều cho phép nhà phát triển tuỳ chỉnh thông số kỹ thuật của ảnh động bằng tham số AnimationSpec
tuỳ chọn.
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
Có nhiều loại AnimationSpec
khác nhau để tạo các loại ảnh động khác nhau.
Tạo ảnh động dựa trên vật lý bằng spring
spring
tạo một ảnh động dựa trên kiến thức vật lý giữa giá trị bắt đầu và giá trị kết thúc. Nội dung này
có 2 thông số: dampingRatio
và stiffness
.
dampingRatio
xác định khả năng bật của spring. Giá trị mặc định là Spring.DampingRatioNoBouncy
.
Hình 1. Đặt các tỷ lệ giảm chấn lò xo khác nhau.
stiffness
xác định tốc độ chuyển động của spring hướng về giá trị cuối cùng. Giá trị mặc định là Spring.StiffnessMedium
.
Hình 2. Đặt độ cứng lò xo khác nhau
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
spring
có thể xử lý sự cố gián đoạn một cách mượt mà hơn các mã AnimationSpec
dựa trên thời lượng
vì các mã này đảm bảo tính liên tục của tốc độ khi
giá trị mục tiêu thay đổi giữa các nội dung ảnh động. spring
được sử dụng như thông số ảnh động mặc định
của nhiều API ảnh động, chẳng hạn như animate*AsState
và
updateTransition
.
Ví dụ: nếu chúng ta áp dụng cấu hình spring
cho ảnh động sau đây do thao tác chạm của người dùng, khi làm gián đoạn ảnh động trong khi ảnh động đang diễn ra, bạn có thể thấy rằng việc sử dụng tween
không phản hồi mượt mà như khi sử dụng spring
.
Hình 3. Đặt thông số tween
so với spring
cho ảnh động và làm gián đoạn ảnh động.
Tạo ảnh động giữa giá trị bắt đầu và giá trị kết thúc bằng easing curve với tween
tween
tạo ảnh động giữa giá trị bắt đầu và giá trị kết thúc qua việc sử dụng một easing curve durationMillis
được chỉ định. tween
là viết tắt của từ between (giữa) vì nó nằm giữa hai giá trị.
Bạn cũng có thể chỉ định delayMillis
để trì hoãn việc bắt đầu ảnh động.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Hãy xem phần Easing để biết thêm thông tin.
Tạo ảnh động cho các giá trị cụ thể tại các thời điểm nhất định bằng keyframes
keyframes
tạo ảnh động dựa trên các giá trị ảnh chụp nhanh được chỉ định tại các dấu thời gian trong suốt thời gian tạo ảnh động. Tại một thời điểm bất kỳ, giá trị ảnh động sẽ được tự ý thêm vào giữa 2 giá trị khung hình chính. Đối với mỗi
khung hình chính, bạn có thể chỉ định Easing để xác định đường cong nội suy.
Có thể tuỳ chọn chỉ định các giá trị ở 0 giây và tại khoảng thời gian. Nếu bạn không chỉ định các giá trị này, thì giá trị mặc định lần lượt là giá trị bắt đầu và kết thúc của ảnh động.
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
Lặp lại ảnh động bằng repeatable
repeatable
chạy một ảnh động dựa trên thời lượng (chẳng hạn như tween
hoặc keyframes
)
lặp lại cho đến khi ảnh động đạt đến số vòng lặp được chỉ định. Bạn có thể chuyển thông số
repeatMode
để chỉ định xem ảnh động nên lặp lại bằng cách
bắt đầu từ đầu (RepeatMode.Restart
) hay từ cuối
(RepeatMode.Reverse
).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Lặp lại ảnh động vô hạn bằng infiniteRepeatable
infiniteRepeatable
giống như repeatable
nhưng số lượng vòng lặp lại là vô hạn.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
Trong các thử nghiệm sử dụng
ComposeTestRule
,
các ảnh động sử dụng infiniteRepeatable
sẽ không chạy. Thành phần sẽ được
hiển thị bằng việc sử dụng giá trị ban đầu của từng giá trị ảnh động.
Ngay lập tức chuyển sang giá trị kết thúc bằng snap
snap
là một AnimationSpec
đặc biệt sẽ ngay lập tức chuyển giá trị đó
sang giá trị kết thúc. Bạn có thể chỉ định delayMillis
để hoãn việc khởi động
ảnh động.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Đặt hàm easing tuỳ chỉnh
Các thao tác AnimationSpec
dựa trên thời lượng (chẳng hạn như tween
hoặc keyframes
) sử dụng
Easing
để điều chỉnh một phân đoạn của ảnh động. Các hoạt động này cho phép giá trị ảnh động
tăng tốc và chậm lại, thay vì di chuyển với tốc độ không đổi. Một phân đoạn là một
giá trị nằm trong khoảng từ 0 (bắt đầu) đến 1.0 (kết thúc) cho biết điểm hiện tại trong
ảnh động.
Easing thực chất là một hàm nhận giá trị phân số từ 0 đến 1.0 và trả về một số thực có độ chính xác đơn. Giá trị được trả về có thể nằm ngoài ranh giới đại diện cho tình trạng quá mức hoặc không đạt mức. Hàm Easing tuỳ chỉnh có thể được tạo giống như mã bên dưới.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
Compose cung cấp nhiều hàm Easing
được tích hợp sẵn cho hầu hết các trường hợp sử dụng.
Hãy xem bài viết Tốc độ – Material Design để biết thêm thông tin về cách sử dụng hàm Easing theo tình huống của bạn.
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- Xem thêm
Tạo ảnh động cho các loại dữ liệu tuỳ chỉnh bằng cách chuyển đổi sang và từ AnimationVector
Theo mặc định, hầu hết các API ảnh động trong Compose đều hỗ trợ Float
, Color
, Dp
và các kiểu dữ liệu cơ bản khác làm giá trị ảnh động, nhưng đôi khi bạn cần tạo ảnh động cho các loại dữ liệu khác, bao gồm cả dữ liệu tuỳ chỉnh. Trong suốt thời gian tạo ảnh động, mọi giá trị ảnh động đều được biểu thị dưới dạng AnimationVector
. Giá trị được chuyển đổi thành AnimationVector
và ngược lại bằng TwoWayConverter
tương ứng để hệ thống ảnh động chính có thể xử lý thống nhất. Ví dụ: Int
được biểu thị dưới dạng AnimationVector1D
và có một giá trị số thực duy nhất.
TwoWayConverter
cho Int
có dạng như:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color
cơ bản là một tập hợp gồm 4 giá trị: đỏ, xanh lá cây, xanh lam và alpha, vì vậy, Color
được chuyển đổi thành AnimationVector4D
chứa 4 giá trị số thực chính xác. Bằng cách này mọi loại dữ liệu sử dụng trong ảnh động sẽ được chuyển đổi thành AnimationVector1D
, AnimationVector2D
, AnimationVector3D
hoặc AnimationVector4D
tuỳ thuộc vào kích thước. Điều này cho phép các thành phần khác nhau của đối tượng được tạo ảnh động độc lập, mỗi thành phần có theo dõi vận tốc riêng. Bạn có thể truy cập các bộ chuyển đổi tích hợp cho kiểu dữ liệu cơ bản bằng cách sử dụng các bộ chuyển đổi như Color.VectorConverter
hoặc Dp.VectorConverter
.
Khi muốn hỗ trợ thêm cho một loại dữ liệu mới dưới dạng giá trị ảnh động, bạn có thể tạo TwoWayConverter
riêng của mình và cung cấp dữ liệu đó cho API. Ví dụ: bạn có thể sử dụng animateValueAsState
để tạo ảnh động cho loại dữ liệu tuỳ chỉnh của mình như sau:
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
Danh sách sau đây bao gồm một số VectorConverter
tích hợp:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Ảnh động dựa trên giá trị
- Phát triển mã lặp lại {:#iterative-code-dev }
- Ảnh động trong Compose