Compose筆記(二十一)--AnimationVisibility

? ? ? ? 這一節主要了解一下Compose的AnimationVisibility,AnimatedVisibility 是 Jetpack Compose 里用于實現組件可見性動畫效果的組件,借助它能讓組件在顯示和隱藏時帶有平滑的過渡動畫,從而提升用戶體驗。現總結如下:

API
1. visible
含義:這是一個布爾類型的參數,用于控制組件的可見性。當 visible為true時,組件會顯示;當visible為false時,組件會隱藏。
作用:它是控制組件顯示與隱藏的核心參數,配合動畫效果可以實現平滑的過渡。
2. enter
含義:指定組件進入(顯示)時的動畫效果。enter參數接收一個EnterTransition類型的值,Compose提供了多種內置的進入動畫,如fadeIn()、slideInHorizontally()等,也可以自定義進入動畫。
作用:讓組件在顯示時帶有動畫效果,增強界面的動態感和視覺效果。
3. exit
含義:指定組件退出(隱藏)時的動畫效果。exit參數接收一個ExitTransition 類型的值,Compose提供了多種內置的退出動畫,如fadeOut()、slideOutHorizontally()等,也可以自定義退出動畫。
作用:讓組件在隱藏時帶有動畫效果,使界面的變化更加平滑自然。
4. initiallyVisible
含義:這是一個布爾類型的可選參數,用于設置組件的初始可見性。默認值為true,即組件在初始狀態下是可見的。
作用:方便在組件首次顯示時就設置其可見性,結合動畫效果可以實現更豐富的界面展示。
5. content
含義:它是一個@Composable函數,用于定義要顯示或隱藏的組件內容。
作用:將需要進行可見性動畫的組件包裹在content函數中,以便應用動畫效果。

常見動畫類型:
1. 淡入動畫(fadeIn)
?讓組件在顯示時從透明逐漸變為不透明,實現淡入效果。
2 淡出動畫(fadeOut)
?讓組件在隱藏時從不透明逐漸變為透明,實現淡出效果。
3 滑入動畫(slideIn)
?slideInHorizontally:使組件從水平方向滑入屏幕。
4 滑出動畫(slideOut)
slideOutHorizontally:使組件從水平方向滑出屏幕。
5. 縮放進入動畫(scaleIn)
?讓組件在顯示時從較小的尺寸逐漸放大到正常尺寸。
6. 縮放退出動畫(scaleOut)
讓組件在隱藏時從正常尺寸逐漸縮小。

栗子:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp@Composable
fun TestAnimatedVisibilityOne() {var isCardVisible by remember { mutableStateOf(false) }var isTextVisible by remember { mutableStateOf(false) }Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceEvenly) {Button(onClick = { isCardVisible = !isCardVisible }) {Text(text = if (isCardVisible) "隱藏卡片" else "顯示卡片")}Button(onClick = { isTextVisible = !isTextVisible }) {Text(text = if (isTextVisible) "隱藏文本" else "顯示文本")}}Spacer(modifier = Modifier.height(20.dp))AnimatedVisibility(visible = isCardVisible,enter = slideInHorizontally(initialOffsetX = { -it },animationSpec = tween(durationMillis = 500)) + fadeIn(animationSpec = tween(durationMillis = 500)),exit = slideOutHorizontally(targetOffsetX = { -it },animationSpec = tween(durationMillis = 500)) + fadeOut(animationSpec = tween(durationMillis = 500))) {Card(modifier = Modifier.fillMaxWidth().padding(16.dp)) {Text(text = "這是一個卡片組件",modifier = Modifier.padding(16.dp))}}Spacer(modifier = Modifier.height(20.dp))AnimatedVisibility(visible = isTextVisible,enter = slideInHorizontally(initialOffsetX = { it },animationSpec = tween(durationMillis = 500)) + fadeIn(animationSpec = tween(durationMillis = 500)),exit = slideOutHorizontally(targetOffsetX = { it },animationSpec = tween(durationMillis = 500)) + fadeOut(animationSpec = tween(durationMillis = 500))) {Box(modifier = Modifier.fillMaxWidth().padding(16.dp),contentAlignment = Alignment.Center) {Text(text = "這是一個文本組件")}}}
}

分析:主要演示當點擊按鈕時,卡片和文本會以不同的動畫效果顯示或隱藏。

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp@Composable
fun TestAnimatedVisibility() {val items = remember {mutableStateListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5")}val expandedIndices = remember { mutableStateListOf<Int>() }LazyColumn(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.spacedBy(16.dp),contentPadding = androidx.compose.foundation.layout.PaddingValues(16.dp)) {itemsIndexed(items) { index, item ->Card(modifier = Modifier.fillMaxWidth()) {Column(modifier = Modifier.padding(16.dp)) {Button(onClick = {if (expandedIndices.contains(index)) {expandedIndices.remove(index)} else {expandedIndices.add(index)}},modifier = Modifier.fillMaxWidth()) {Text(text = item)}AnimatedVisibility(visible = expandedIndices.contains(index),enter = expandVertically(expandFrom = Alignment.Top) + fadeIn(initialAlpha = 0.3f),exit = shrinkVertically() + fadeOut()) {Text(text = "這是 $item 的詳細信息",modifier = Modifier.padding(top = 8.dp))}}}}}
}

分析: AnimatedVisibility 與列表結合使用。當點擊列表項時,該項的詳細信息會以動畫形式展開或收縮。

注意:
1 狀態管理不當引發的問題,如果沒有正確管理 AnimatedVisibility 的可見性狀態,可能會出現動畫不按預期執行,或者在重組時狀態丟失的情況。
2 動畫配置沖突 當組合多個動畫時,如果動畫的配置相互沖突,可能會導致動畫效果不符合預期,甚至出現卡頓現象。
3 動畫完成回調缺失,AnimatedVisibility 本身沒有直接提供動畫完成的回調,若需要在動畫完成后執行特定操作,會比較麻煩,可以借助 LaunchedEffect 和 AnimatedVisibilityState 來監聽動畫的完成狀態。

源碼:

@Composable
fun AnimatedVisibility(visible: Boolean,modifier: Modifier = Modifier,enter: EnterTransition = fadeIn() + expandVertically(),exit: ExitTransition = shrinkVertically() + fadeOut(),initiallyVisible: Boolean = true,content: @Composable () -> Unit
) {// 管理可見性狀態val visibilityState = rememberAnimatedVisibilityState(initiallyVisible = initiallyVisible,visible = visible)// 應用動畫AnimatedVisibilityImpl(visibilityState = visibilityState,modifier = modifier,enter = enter,exit = exit,content = content)
}

分析:
visible:控制組件的可見性。
enter和exit:分別指定進入和退出動畫。
initiallyVisible:設置組件的初始可見性。
content:要顯示或隱藏的組件內容。
調用rememberAnimatedVisibilityState函數創建并管理可見性狀態。
調用AnimatedVisibilityImpl 函數應用動畫。

@Composable
fun rememberAnimatedVisibilityState(initiallyVisible: Boolean,visible: Boolean
): AnimatedVisibilityState {val state = remember { AnimatedVisibilityState(initiallyVisible) }LaunchedEffect(visible) {if (visible) {state.show()} else {state.hide()}}return state
}

分析:
使用 remember 函數創建并存儲 AnimatedVisibilityState 實例。
通過 LaunchedEffect監聽visible參數的變化,當visible改變時,調用state.show()或state.hide()方法觸發動畫。

class AnimatedVisibilityState(initiallyVisible: Boolean) {var targetVisibility by mutableStateOf(initiallyVisible)var isVisible: Booleanget() = targetVisibility || isAnimationRunningprivate set(_) {}var isAnimationRunning by mutableStateOf(false)suspend fun show() {if (targetVisibility) returntargetVisibility = trueisAnimationRunning = truetry {// 執行進入動畫// 這里會根據具體的 EnterTransition 執行動畫邏輯} finally {isAnimationRunning = false}}suspend fun hide() {if (!targetVisibility) returntargetVisibility = falseisAnimationRunning = truetry {// 執行退出動畫// 這里會根據具體的 ExitTransition 執行動畫邏輯} finally {isAnimationRunning = false}}
}

分析:
targetVisibility:存儲目標可見性狀態。
isVisible:表示組件當前是否可見,考慮了動畫執行狀態。
isAnimationRunning:記錄動畫是否正在執行。
show()和hide()方法:分別觸發進入和退出動畫,在動畫執行期間將isAnimationRunning設置為true,動畫結束后設置為false。

AnimatedVisibilityImpl 函數

@Composable
private fun AnimatedVisibilityImpl(visibilityState: AnimatedVisibilityState,modifier: Modifier,enter: EnterTransition,exit: ExitTransition,content: @Composable () -> Unit
) {if (visibilityState.isVisible) {// 根據動畫狀態應用過渡效果val transition = updateTransition(visibilityState.targetVisibility, label = "AnimatedVisibility")val enterFraction = transition.animateFloat(transitionSpec = { enter.animationSpec },label = "EnterFraction") { targetVisible ->if (targetVisible) 1f else 0f}.valueval exitFraction = transition.animateFloat(transitionSpec = { exit.animationSpec },label = "ExitFraction") { targetVisible ->if (targetVisible) 0f else 1f}.value// 根據動畫進度應用修飾符val animatedModifier = modifier.then(enter.createModifier(enterFraction)).then(exit.createModifier(exitFraction))// 顯示組件內容Box(animatedModifier) {content()}}
}

分析:
若visibilityState.isVisible為true,則創建 updateTransition來管理動畫過渡。
分別計算進入和退出動畫的進度enterFraction和exitFraction。
根據動畫進度應用enter和 exit 動畫的修飾符。
使用Box組件包裹content,并應用動畫修飾符。
? ? ? ? 簡而言之,AnimatedVisibility 的源碼核心在于狀態管理和動畫調度。通過 AnimatedVisibilityState管理可見性狀態和動畫執行狀態,利用updateTransition實現動畫過渡,最終根據動畫進度動態調整組件的屬性,實現平滑的可見性動畫效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903623.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903623.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903623.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于 HT 構建 2D 智慧倉儲可視化系統的技術解析

在當今數字化時代&#xff0c;倉儲管理對于企業的運營效率和成本控制愈發關鍵。圖撲軟件&#xff08;Hightopo&#xff09;憑借其強大的 HT for Web 產品&#xff0c;打造出 2D 智慧倉儲可視化平臺&#xff0c;為倉儲管理帶來了全新的技術解決方案。 HT 是一款基于 WebGL、can…

HTML ASCII 編碼詳解

HTML ASCII 編碼詳解 引言 HTML&#xff08;HyperText Markup Language&#xff09;是一種用于創建網頁的標準標記語言。在HTML中&#xff0c;字符的表示方式非常重要&#xff0c;因為它直接影響到網頁內容的顯示效果。ASCII編碼作為一種基本的字符編碼方式&#xff0c;在HTM…

pinia-plugin-persistedstate的使用

pinia持久化存儲的使用 安裝 npm install pinia-plugin-persistedstate 注冊 import { createPinia } from pinia import piniaPluginPersistedstate from pinia-plugin-persistedstateconst pinia createPinia() pinia.use(piniaPluginPersistedstate)export default pinia …

Vue:el-table-tree懶加載數據

目錄 一、出現場景二、具體使用三、修改時重新加載樹節點四、新增、刪除重新加載樹節點 一、出現場景 在項目的開發過程中&#xff0c;我們經常會使用到表格樹的格式&#xff0c;但是猶豫數據較多&#xff0c;使用分頁又不符合項目需求時&#xff0c;就需要對樹進行懶加載的操…

ChipCN IDE KF32 導入工程后,無法編譯的問題

使用ChipON IDE for KungFu32 導入已有的工程是時&#xff0c;發現能夠編譯&#xff0c;但是點擊&#xff0c;同時選擇硬件調試時 沒有任何響應。查看工程調試配置時&#xff0c;發現如下問題&#xff1a; 沒有看到添加有啟動配置&#xff0c;說明就是這里的問題了(應該是IDE的…

前端筆記-Element-Plus

結束了vue的基礎學習&#xff0c;現在進一步學習組件 Element-Plus部分學習目標&#xff1a; Element Plus1、查閱官方文檔指南2、學習常用組件的使用方法3、Table、Pagination、Form4、Input、Input Number、Switch、Select、Date Picker、Button5、Message、MessageBox、N…

C++入門小館: 模板

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

強化學習之基于無模型的算法之基于值函數的深度強化學習算法

3、基于值函數的深度強化學習算法 1&#xff09;深度Q網絡&#xff08;DQN&#xff09; 核心思想 DQN是一種將Q學習與深度神經網絡結合的方法&#xff0c;用于解決高維狀態空間的問題。 它以環境的狀態作為輸入&#xff0c;通過神經網絡輸出每個動作的 Q 值&#xff0c;智能體…

網絡規劃和設計

1.結構化綜合布線系統包括建筑物綜合布線系統PDS&#xff0c;智能大夏布線系統IBS和工業布線系統IDS 2.GB 50311-2016綜合布線系統工程設計規范 GB/T 50312-2016綜合布線系統工程驗收規范 3.結構化布線系統分為6個子系統&#xff1a; 工作區子系統&#xff1b;水平布線子系…

軟件設計師-錯題筆記-計算機硬件和體系

1. 解析&#xff1a;循環冗余校驗碼也叫CRC校驗碼&#xff0c;其中運算包括了模2&#xff08;異或&#xff09;來構造校驗位。別的三種沒有用到模2的方法。 2. 解析&#xff1a;如果是正數&#xff0c;則是首位為0&#xff0c;其余位全為1&#xff0c;這時最大數(2^(n-1))-1…

OpenCV 4.7企業級開發實戰:從圖像處理到目標檢測的全方位指南

簡介 OpenCV作為工業級計算機視覺開發的核心工具庫,其4.7版本在圖像處理、視頻分析和深度學習模型推理方面實現了顯著優化。 本文將從零開始,系統講解OpenCV 4.7的核心特性和功能更新,同時結合企業級應用場景,提供詳細代碼示例和實戰項目,幫助讀者掌握從基礎圖像處理到復…

LeetCode算法題 (除自身以外數組的乘積)Day14!!!C/C++

https://leetcode.cn/problems/product-of-array-except-self/description/ 一、題目分析 給你一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據 保證 數組 nums之中任意元素的全部前綴…

如何寫好Verilog狀態機

還記得之前軟件的同事說過的一句話。怎么凸顯自己的工作量&#xff0c;就是自己給自己寫BUG。 看過夏宇聞老師書的都知道&#xff0c;verilog的FSM有moore和mealy,然后有一段&#xff0c;二段&#xff0c;三段式。記得我還是學生的時候&#xff0c;看到這里的時候&#xff0c;感…

晶振頻率/穩定度/精度/溫度特性的深度解析與測量技巧

在電子設備的精密世界里&#xff0c;晶振如同跳動的心臟&#xff0c;為各類系統提供穩定的時鐘信號。晶振的頻率、穩定度、精度以及溫度特性&#xff0c;這些關鍵參數不僅決定了設備的性能&#xff0c;更在不同的應用場景中發揮著至關重要的作用。 一、頻率選擇的本質&#xff…

Kafka-可視化工具-Offset Explorer

安裝&#xff1a; 下載地址&#xff1a;Offset Explorer 安裝好后如圖&#xff1a; 1、下載安裝完畢&#xff0c;進行新增連接&#xff0c;啟動offsetexplorer.exe&#xff0c;在Add Cluster窗口Properties 選項下填寫Cluster name 和 kafka Cluster Version Cluster name (集…

LabVIEW模板之溫度監測應用

這是一個溫度監測應用程序&#xff0c;基于 Continuous Measurement and Logging 示例項目構建&#xff0c;用于讀取模擬溫度值&#xff0c;當溫度超出給定范圍時發出警報 。 這個。 詳細說明 運行操作&#xff1a;直接運行該 VI 程序。點擊 “Start” 按鈕&#xff0c;即可開…

后端[特殊字符][特殊字符]看前端之Row與Col

是的&#xff0c;在 Ant Design 的柵格布局系統中&#xff0c;每個 <Row> 組件確實對應頁面上的一個獨立行。以下是更詳細的解釋&#xff1a; 核心概念 組件作用類比現實場景<Row>橫向容器&#xff0c;定義一行內容類似 Excel 表格中的一行<Col>縱向分割&am…

[特殊字符] SpringCloud項目中使用OpenFeign進行微服務遠程調用詳解(含連接池與日志配置)

&#x1f4da; 目錄 為什么要用OpenFeign&#xff1f; 在cart-service中整合OpenFeign 2.1 引入依賴 2.2 啟用OpenFeign 2.3 編寫Feign客戶端 2.4 調用Feign接口 開啟連接池&#xff0c;優化Feign性能 3.1 引入OkHttp 3.2 配置啟用OkHttp連接池 3.3 驗證連接池生效 Feign最佳…

VARIAN安捷倫真空泵維修清潔保養操作SOP換油操作流程內部轉子圖文并茂內部培訓手側

VARIAN安捷倫真空泵維修清潔保養操作SOP換油操作流程內部轉子圖文并茂內部培訓手側