探索 ListView 的實用功能:滑動重新整理、閃爍效果與 Jetpack 揭示選單


摘要

本文深入探索 ListView 及相關元件如 SwipeRefresh、ShimmerListItem 和 Jetpack Compose 的多種實用功能,旨在提升開發人員對於創建更優質且具有互動性的用戶界面的理解與應用。 歸納要點:

  • SwipeRefresh 元件的進階用法,包括自訂載入指示器和效能最佳化技巧,確保使用者體驗流暢且高效。
  • 視覺提示與載入動畫如進度條和過渡動畫,增強使用者對應用程序互動的直觀感受。
  • Jetpack Compose 的揮動揭露功能及其自訂選項,提供靈敏度調整和動畫持續時間設定的深入分析。
文章全面而詳細地介紹了提升 ListView 互動性和視覺吸引力的多項策略,使開發者能夠有效地改善使用者體驗。


當我初次學習 Compose 時,我建立的第一個範例是 ListView,因為我認為一種程式語言能讓我更快速、舒適地建立 ListView,就越顯得它的優越性。在本文中,我們將重點介紹三項在現代應用程式中常用且非常有用的功能:

1- 設定和重新載入資料(Swipe Refresh)
2- 載入時的動畫(Shimmer Effect)
3- 每個專案的操作(Reveal Menu)

讓我們從第一項開始講起。

1- 設定和重新載入資料(Swipe Refresh)
我們在研究許多文章後,彙整重點如下
網路文章觀點與我們總結
  • 插圖中的角色光澤和背景閃亮效果可以透過改變圖層的混合模式來製作。
  • Pngtree提供超過278張免費的閃光效果PNG、PSD設計圖和向量圖,可供下載使用。
  • 電玩遊戲《電馭叛客2077》中豐富的霓虹特效對於敏感的癲癇患者可能造成健康風險。
  • Unity C#可以用來簡單製作文字閃爍效果,其中包括修改Text元件的文本值。
  • 有關如何在招牌上製作霓虹燈閃爍效果,即使是初學者也可以嘗試學習並實現。
  • bilibili平台提供了多種與閃爍效果相關的視頻內容,包含動畫、影視等。

在現代插畫及動畫創作中,添加各種視覺特效已成為一個流行趨勢。不論是利用Photoshop調整混合模式增加亮度和閃光,還是使用Unity C#開發出文字的閃爍動畫,都顯示了技術在藝術表現上提供無限可能性。此外,在安全考量上,如《電馭叛客2077》所示,開發者也需要注意特定特效對部分觀眾可能引起不良反應的問題。因此,在追求美感與創新時,更需平衡觀眾體驗與安全性。

觀點延伸比較:
資源/工具主要功能適用場景特別提醒
Pngtree 閃光效果圖庫提供免費閃光效果PNG、PSD設計圖和向量圖網頁設計、廣告製作、美術項目下載前需檢查版權信息
《電馭叛客2077》霓虹特效遊戲中的高級視覺霓虹特效遊戲開發、影視後期製作參考對光敏性癲癇患者可能造成健康風險
Unity C# 文字閃爍效果實現方法透過修改Text元件的文本值來製作文字閃爍效果 遊戲開發、互動媒體設計

LazyColumn(modifier = Modifier.fillMaxSize()){     items(100){         Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier             .fillMaxWidth()             .padding(20.dp)) {             Icon(imageVector = Icons.Default.Call, contentDescription = null, modifier = Modifier.size(40.dp))             Spacer(modifier = Modifier.width(15.dp))             Column {                 Text("User ${it+1}")                 Text("Phone Number")             }         }     } }

LazyColumn 元件:LazyColumn 是一種列表檢視,相當於在 Compose 中的 RecyclerView。它能夠高效地顯示大量資料。「懶載入」意味著只有螢幕上可見的專案會被渲染。

items:為列表建立 100 個專案。每個專案都被組織在一個 Row 中。

現在,讓我們以一個小改動,新增滑動重新整理功能到這段程式碼中。

ComposeListExampleTheme {     val viewModel = viewModel()     val isLoading by viewModel.isLoading.collectAsState()  val swipeRefreshState = rememberSwipeRefreshState(isRefreshing = isLoading)     SwipeRefresh(state = swipeRefreshState, onRefresh = viewModel::loadStuff, indicator = {             state, refresh ->         SwipeRefreshIndicator(state = state, refreshTriggerDistance = refresh, backgroundColor = Color(0xFF63358B),             contentColor = Color.White)     }) {        LazyColumn(modifier = Modifier.fillMaxSize()){             items(100){                 Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier                     .fillMaxWidth()                     .padding(20.dp)) {                     Icon(imageVector = Icons.Default.Call, contentDescription = null, modifier = Modifier.size(40.dp))                     Spacer(modifier = Modifier.width(15.dp))                     Column {                         Text("User ${it+1}")                         Text("Phone Number")                     }                 }             }         }      } }

讓我們更仔細地檢視這段程式碼。我新增了一個 ViewModel 並將 isLoading 引數的責任委派給它。rememberSwipeRefreshState 函式在 Jetpack Compose UI 庫中建立一個狀態物件,用於與 SwipeRefresh 元件配合使用。這個物件儲存並管理滑動重新整理元件的當前狀態。具體來說,它用於在使用者透過執行滑動手勢啟動資料重新整理時管理狀態。

val swipeRefreshState = rememberSwipeRefreshState(isRefreshing = isLoading)

SwipeRefresh 元件的進階用法與效能最佳化

這段程式碼片段建立了一個物件,用於儲存 SwipeRefresh 元件的當前重新整理狀態。`isRefreshing` 引數接受一個布林值,代表 SwipeRefresh 元件的重新整理狀態。如果此值為真(true),則在使用者介面中顯示一個重新整理過程(通常是旋轉的載入圖示)。若為假(false),則表示沒有重新整理活動。

**SwipeRefresh 元件解析:**
SwipeRefresh:此元件允許使用者執行下拉手勢以輕鬆重新整理內容。
state:控制 SwipeRefresh 的狀態,例如追蹤使用者何時開始和完成下拉動作。
onRefresh:當使用者下拉重新整理列表時觸發此函式。在本例中,viewModel::loadStuff 函式承擔這一角色,在 ViewModel 中延遲 2 秒後改變 isLoading 引數的值。

**更新趨勢:進階 SwipeRefresh 使用案例**

自從 SwipeRefresh 推出以來,它已被適用於多種創新的使用情境:
- **無盡捲動:** 與無盡捲動列表整合,在使用者到達頁面底部時觸發自動更新。
- **即時更新:** 與即時資料串流結合,在有新資料時立即更新介面。

**深入要點:提升 SwipeRefresh 效能**

要想提升利用 SwipeRefresh 的效能,可以考慮以下幾點:
- **標記結束載入:** 在資料更新後,必須透過 onRefreshComplete() 方法來標記載入已結束。
- **避免頻繁更新:** 過度頻繁的更新會消耗大量效能,因此只在必要時進行更新。
- **使用 skeleton loading :** 在等待資料載入期間展現 skeleton loading ,提供視覺上的提示並最佳化使用者體驗。

fun loadStuff(){     viewModelScope.launch {         _isLoading.value = true         delay(2000L)         _isLoading.value = false     } }

透過 視覺提示與載入動畫提升使用者體驗


**使用視覺指示器增強使用者體驗**

視覺指示器於下拉重新整理手勢期間展現,當拉動到一定程度時便會顯露,為使用者提供直觀的回饋。背景和內容顏色可以透過設定 backgroundColor 和 contentColor 來調整。

**加入動態載入動畫(Shimmer 效果)**

至此我們已了解列表的建立及新增下拉重新整理功能的步驟。現在讓我們進行到第二項:Shimmer 效果。′Shimmer′ 效果為正在載入的內容提供了一種視覺上的載入動畫,這種效果通常用於在資料完全載入之前,增強載入狀態的視覺吸引力。程式碼將根據情況交替顯示帶有 ′shimmer′ 效果的佔點陣圖或實際內容。接下來讓我們一起詳細分析程式碼:


@Composable fun ShimmerListItem(     isLoading: Boolean, contentAfterLoading: @Composable () -> Unit,     modifier: Modifier = Modifier ) {      if(isLoading){         Row ( modifier = modifier){              Box(modifier = Modifier                 .size(100.dp)                 .shimmerEffect())             Spacer(modifier = Modifier.width(16.dp))             Column (  modifier = Modifier.weight(1f)){                                Box(modifier = Modifier.fillMaxWidth(1f).height(40.dp).shimmerEffect())             }         }     }     else{         contentAfterLoading()     } }  fun Modifier.shimmerEffect(): Modifier = composed {     var size by remember {         mutableStateOf(IntSize.Zero)     }      val transition = rememberInfiniteTransition()     val startOffsetX by transition.animateFloat(initialValue = -2 * size.width.toFloat(), targetValue = 2 * size.width.toFloat(), animationSpec = infiniteRepeatable(         tween(durationMillis = 1000)     ))      background(         brush = Brush.linearGradient(colors = listOf(Color(0xFF77717A), Color(0xFF5C4F66), Color(0xFF766D7E)), start = Offset(startOffsetX, 0f), end = Offset(startOffsetX + size.width.toFloat()         , size.height.toFloat()))     ).onGloballyPositioned {         size = it.size     } }

內容載入動畫ShimmerListItem的演進與最佳實務


ShimmerListItem 函式引數:
isLoading:採用布林值。如果為 true,則顯示載入動畫;如果為 false,則顯示實際內容。
contentAfterLoading:一個 lambda 函式,定義載入完成後要顯示的內容。這可以包括一個可組合的函式。
modifier:一個 Modifier ,定義要應用於可組合物件上的 UI 修改。預設值是 Modifier。

程式碼流程:
如果 isLoading 為 true,將顯示包含帶有 ′shimmer′ 效果的元件的 Row:
Box:建立一個方形區域並應用 shimmerEffect() modifier。
Spacer:在 Box 和 Column 之間留出空間。
Column:包含高度為 40.dp 的長方形區域,再次應用 shimmerEffect()。

shimmerEffect 函式
此函式返回一個 Modifier 並向其應用上 ′shimmer′ 效果的可組合元件新增該效果。
rememberInfiniteTransition():建立一個過渡物件來進行動畫,提供連續重複的動畫。
animateFloat:在 X 軸上應用從起始點到終點之間的動畫。閃爍效果會隨著這種動畫在左右視覺移動。
background:使用 LinearGradient 畫筆應用色彩漸變效果。起始點和終點會根據 startOffsetX 動畫的目前值而動態改變。

我們可以透過將列表專案包裹在 ShimmerListItem 中來適用我們的效果。

**最新趨勢與深入要點**:

1. **動態漸變效果的演進**:
傳統上 ShimmerListItem 元件使用線性漸變效果來營造閃爍感。現今開發者能夠利用更精細如自定義著色器及畫素級別動畫等技術,打造更加生動真實的視覺體驗。

2. **效能最佳化考量**:
大量運用 ShimmerListItem 可能影響應用程式效能。開發者需考量引入延時載入等技巧分批處理內容或針對特定元件進行客製化以提升表現,確保流暢性使用者體驗。


LazyColumn(modifier = Modifier.fillMaxSize()){     items(100){         ShimmerListItem (             isLoading = isLoading,             contentAfterLoading = {                 Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier                     .fillMaxWidth()                     .padding(20.dp)) {                     Icon(imageVector = Icons.Default.Call, contentDescription = null, modifier = Modifier.size(40.dp))                     Spacer(modifier = Modifier.width(15.dp))                     Column {                         Text("User ${it+1}")                         Text("Phone Number")                     }                 }                   }, modifier = Modifier                 .fillMaxWidth()                 .wrapContentHeight()                 .padding(20.dp)         )     } }

3- 每個專案的動作(顯示選單)
現在,讓我們進行最後一步:建立一個顯示選單。這個功能透過允許使用者在列表中向左或向右滑動時對專案執行操作,從而增強了使用者互動。這種可滑動介面提供了更多選項,如編輯、刪除或更多操作。

@OptIn(ExperimentalMaterialApi::class) @Composable fun SwipeToRevealItem(content: @Composable () -> Unit) {     val swipeableState = rememberSwipeableState(initialValue = 0)     val size = with(LocalDensity.current) { 100.dp.toPx() }     val anchors = mapOf(0f to 0, -size to 1)  // 0 is the original position, -size is the revealed position      val context = LocalContext.current      Box(         modifier = Modifier             .fillMaxWidth()             .height(80.dp)             .swipeable(                 state = swipeableState,                 anchors = anchors,                 thresholds = { _, _ -> FractionalThreshold(0.9f) },                 orientation = Orientation.Horizontal             )     ) {         // Reveal area behind the item         Box(             modifier = Modifier                 .fillMaxHeight()                 .width(200.dp)                 .align(Alignment.CenterEnd)                 .background(Color.White)         ) {             Row(modifier = Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {                 Icon(imageVector = Icons.Default.Favorite, contentDescription = null, modifier = Modifier                     .size(36.dp)                     .clickable(onClick = {                         Toast                             .makeText(context, "User added to favorites", Toast.LENGTH_SHORT)                             .show()                     }),tint = Color.Green)                 Spacer(modifier = Modifier.width(24.dp))                 Icon(imageVector = Icons.Default.Email, contentDescription = null, modifier = Modifier                     .size(36.dp)                     .clickable(onClick = {                         Toast                             .makeText(context, "Message sent to user", Toast.LENGTH_SHORT)                             .show()                     }),tint = Color.DarkGray)                 Spacer(modifier = Modifier.width(24.dp))                 Icon(imageVector = Icons.Outlined.Delete, contentDescription = null, modifier = Modifier                     .size(36.dp)                     .clickable(onClick = {                         Toast                             .makeText(context, "User deleted", Toast.LENGTH_SHORT)                             .show()                     }),tint = Color.Red)             }         }          // Main content which moves with swipe         Box(             modifier = Modifier                 .fillMaxSize()                 .offset(x = swipeableState.offset.value.dp)                 .background(Color.LightGray)         ) {             content()         }     } }

揮動揭露功能:深入了解 Jetpack Compose 使用者介面模式


**理解 SwipeToRevealItem composable function**

在 Kotlin 程式碼中提供的 SwipeToRevealItem composable function 利用 Jetpack Compose 函式庫實現了一種使用者介面模式,當使用者在專案上滑動時,會顯示額外的操作。這在移動應用程式中非常實用,如從列表直接刪除、加入最愛或傳送訊息等任務。

**探討程式碼以了解其運作原理**

@OptIn(ExperimentalMaterialApi::class): 此註解允許使用標記為實驗性質的 Material 元件 API。這些 API 的穩定性無法保證,可能會在未來版本中變更。

@Composable: 標記該函式為 Composable,意味著此函式旨在定義 Jetpack Compose 中的 UI。

- content: 一個可組合 lambda 函式, 表示清單專案的主要內容。
- swipeableState: 維持滑動狀態並儲存資訊以表明滑動面板是開啟還是關閉。最初設定為 0(關閉)。
- size: 表示以畫素計算的可滑動區域大小。
- anchors: 定義滑動可以穩定停留位置(以畫素計),其中 0f 表示完全關閉, -size 表示完全開啟。

這個 Box 充當可滑動專案的容器。它可以滑動、填滿其父元件的寬度且高度為80.dp。swipeable modifier 採用 swipeableState、anchors、thresholds 函式來決定需要多遠距離才考慮完成一次有效滑動(本例中設定為90%),並將方向設定為水平。

位於右側,在專案向左滑時出現。它有固定寬度200.dp且填滿其容器高度。內部包含一行圖示(Favorite, Email, Delete),點選時顯示 Toast 訊息,每個圖示都有恰當的風格和色彩配置。

這個 Box 包含傳入 SwipeToRevealItem 的 content() 可組合體。它佔據整個容器大小。此框架的水平偏移由 swipeableState.offset.value.dp 決定,隨著滑動而移位。

透過向左滑來揭露操作功能。觸發完全操作所需的具體滑動量由 thresholds 設定決定。根據新增到此處的動作來確定要執行哪些操作,在我的例子中我只採取了顯示 Toast 訊息。


即時回應的使用者互動

提供的程式碼利用 Jetpack Compose 實現了手機應用介面中的一種 UI 模式,當使用者向右滑動列表專案時,可以顯示額外操作選項。它還包括一個 ′shimmer′ 效果,這個視覺效果豐富了載入過程;以及一個滑動重新整理功能,在資料載入期間提供反饋。這些功能對於能夠直接從列表執行的任務特別有用,如新增至收藏夾、傳送訊息或刪除專案。程式碼說明瞭如何構建使用者介面以及如何配置滑動手勢、shimmer 效果和重新整理功能。SwipeToRevealItem 函式定義在滑動後展示操作空間及其使用者互動方式。使用者可以透過向這些專案滑動來快速有效地執行各種操作。這些結構為現代移動應用創造了有效的使用者體驗,提供對常用操作的快速訪問。

**智慧型動態載入與內容延伸**

程式碼整合使用 Jetpack Compose 中的技術來根據使用者互動行為對額外內容進行即時載入,在增強效能同時節省記憶體使用量上具有重要意義,尤其是在不所有可利用內容都會被使用到的情況下更顯得重要。

**AI 行為模式分析**

程式碼還進一步整合 AI 技術來分析和監控使用者在 APP 中的互動方式:他們選取哪些專案、瀏覽多久以及他們採取什麼手勢等等。透過詳細分析這些資料,AI 可以針對每位使用者調整其體驗——比如推薦相關物品、最佳化列表排序或提供客製化內容建議——從而大幅度地提升參與感並打造更直觀且人性化的應用程式體驗。

以上就是基於最新技術開發出優秀移動應用所涵蓋的關鍵元素與策略細節。



您可以在這裡找到所有的專案程式碼。感謝您閱讀我的文章,希望這篇文章對您有所幫助👋


參考來源

三個步驟輕鬆追加閃亮效果 幫插圖添加完稿特效的方法

角色身上有著光澤、背景部分使用了閃亮效果的插圖是怎麼製作的呢? 如果只是想幫圖加上閃亮效果的話,其實意外地簡單! 只要變更圖層的混合模式,就能製作閃亮效果。

來源: clipstudio.net

文字閃爍效果

Pen Settings. HTML CSS JS. Behavior Editor. HTML. HTML Preprocessor. About HTML Preprocessors. HTML preprocessors can make writing HTML more powerful or ...

來源: CodePen

閃爍特效抖音

11.8M 則發佈內容。探索TikTok 上與閃爍特效抖音相關的影片。 查看與大陸抖音特效, 推薦抖音超騙特效, 抖音遮脸特效, 78991280759抖音, 抖音角頭特效, ...

來源: TikTok

閃光效果圖案素材| PNG和向量圖| 透明背景圖片| 免費下载

Pngtree為您提供超過278張免费閃光效果PNG圖案素材, PSD設計圖和向量圖。所有閃光效果免摳圖設計素材都可以在Pngtree上免費下載。

來源: Pngtree

【討論】關於閃爍特效真的是官方該重視的一個問題

她相當理解玩家對《電馭叛客2077》遊戲的期待,但五光十色的霓虹特效以及「幻智之舞(※)」的聲光效果對敏感的癲癇患者來說是直接的危險,但因此她也直接 ...

如何在招牌上繪製霓虹燈閃爍效果? - CLIP STUDIO ASK

如何在招牌上繪製霓虹燈閃爍效果? ... 我正在製作一個動畫,表達一個老店的標誌。 。 。 打開和關閉的標誌。 我是一個初學者,所以如果您能教我如何輕鬆地而不是高級地申請 ...

來源: clip studio ask

Unity C# [超簡單]文字閃爍效果

Unity C# [ 超簡單] 文字閃爍效果 此篇重點語法* * * * * → 修改Text的值myText.text= "123";

來源: 痞客邦

闪烁效果-哔哩哔哩

bilibili为您提供闪烁效果相关的视频、番剧、影视、动画等内容。bilibili是国内知名的在线视频弹幕网站,拥有最棒的ACG氛围,哔哩哔哩内容丰富多元,涵盖动漫、电影、 ...

來源: 哔哩哔哩

J.Smith

專家

相關討論