七爪源码JetpackCompose刷卡刷新
关于如何在加载项目时实现滑动刷新功能以及占位符的简短指南
今天,许多应用程序都有需要在某个时候刷新的数据。您可以在一段时间后刷新数据或使用套接字来始终拥有最新的数据,但是如果您想要允许用户开始刷新数据的功能怎么办?
这可以通过一个按钮来完成,但在某些情况下,更好的用户体验将是滑动刷新。今天,我们将使用Accompanist库来实现它。
滑动刷新
首先,让我们添加一个依赖项:implementationcom。google。accompanist:accompanistswiperefresh:0。25。1
注意:检查是否有此依赖项的更新版本。
接下来是创建一个简单的ViewModel,它将保存我们的数据和刷新逻辑。在这里,项目将包含随机图像和数字。这是它的样子:classMainViewModel:ViewModel(){privatevalisRefreshingMutableStateFlow(false)valisRefreshingisRefreshing。asStateFlow()privatevalcurrentTimeMutableStateFlow(Instant。now())valcurrentTimecurrentTime。asStateFlow()privatevalitemsMutableStateFlow(generateItems())valitemsitems。asStateFlow()funrefresh()viewModelScope。launch{isRefreshing。update{true}SimulateAPIcalldelay(2000)currentTime。valueInstant。now()items。valuegenerateItems()isRefreshing。update{false}}privatefungenerateItems():ListRowItem{vallistmutableListOfRowItem()for(iin1until20){list。add(RowItem(rowImagerandomImage(),numberRandom。nextInt(1,1000)))}returnlist}privatefunrandomImage(seed:Int(0。。100000)。random(),width:Int300,height:Intwidth,):String{returnhttps:picsum。photosseedseedwidthheight}}dataclassRowItem(valrowImage:String,valnumber:Int1)
isRefreshing是一个布尔值,我们将在swipeRefreshState中使用它,我们将在后面解释。items只是包含随机图像和数字的20个项目的列表。
现在,让我们创建我们的屏幕:ComposablefunMainScreen(viewModel:MainViewModelviewModel()){valisRefreshingviewModel。isRefreshing。collectAsState()。valuevalcurrentTimeviewModel。currentTime。collectAsState()。valuevalitemsviewModel。items。collectAsState()。valuevalswipeRefreshStaterememberSwipeRefreshState(isRefreshingisRefreshing)SwipeRefresh(stateswipeRefreshState,onRefreshviewModel::refresh,modifierModifier。fillMaxSize()。padding(vertical32。dp,horizontal16。dp)){Column{Text(textWelcometoSwipetoRefresh!,styleMaterialTheme。typography。h5,modifierModifier。fillMaxWidth(),textAlignTextAlign。Center)Spacer(modifierModifier。height(32。dp))Text(textcurrentTime。toString(),modifierModifier。fillMaxWidth(),textAlignTextAlign。End)Spacer(modifierModifier。height(8。dp))LazyColumn{items(items){Item(rowItemit)}}}}}ComposablefunItem(rowItem:RowItem){Card(modifierModifier。fillMaxWidth()。padding(vertical8。dp),elevation4。dp){Row(modifierModifier。fillMaxWidth()。padding(16。dp),verticalAlignmentAlignment。CenterVertically,){Image(painterrememberAsyncImagePainter(rowItem。rowImage),contentDescriptionrowItem。number。toString(),modifierModifier。size(64。dp))Spacer(modifierModifier。width(16。dp))Text(textNumber:{rowItem。number})}}}
我们正在收集我们的状态并使用isRefreshing的值创建swipeRefreshState。我们将这个状态传递给SwipeRefresh,但如果需要,我们也可以访问它的属性isRefreshing和isSwipeInProgress。在SwipeRefresh中,我们有一个标题、当前时间和项目列表。每行项目只显示一个图像和数字。
SwipeRefresh具有三个强制参数:state:SwipeRefreshState可以提升以控制和观察SwipeRefresh更改的状态对象onRefresh:()Unit完成滑动刷新手势时调用的Lambdacontent:Composable()Unit包含可组合滚动的内容
一些有趣的可选参数是:swipeEnabled:Boolean布局是否应该对滑动手势做出反应refreshTriggerDistance:Dp触发刷新的最小滑动距离indicatorAlignment:Alignment指标的对齐方式。默认为Alignment。TopCenterindicatorPadding:PaddingValues指标的内容填充,如果需要可以插入指标indicator:Composable(state:SwipeRefreshState,refreshTrigger:Dp)表示当前状态的指标。默认情况下,这将使用SwipeRefreshIndicator
对于指标参数,您可以创建自己的可组合项,但该库为我们提供了SwipeRefreshIndicator,这是我们可以使用的非常好的可组合项。
它需要两个参数:state:SwipeRefreshState传递到SwipeRefresh指示器块的SwipeRefreshStaterefreshTriggerDistance:Dp触发刷新的最小滑动距离
一些可选参数是:fade:Boolean箭头在滚动时是否应该淡入淡出,默认为truescale:Boolean指示器在滚动时是否应按比例放大缩小,默认为falsearrowEnabled:Boolean是否应在指标上绘制箭头,默认为truebackgroundColor:Color指示器背景表面的颜色
还有更多参数,但不需要全部遍历。如果您想了解更多信息,请务必在官方文档中查看。
这就是SwipeRefresh的全部内容,现在让我们实现占位符,这是来自Accompanist的另一个不错的库。
占位符
通常,项目的加载由某种加载微调器显示。另一种显示项目正在加载的方法是使用占位符。
Accompanist创建了一个库,为我们提供了用于显示占位符的修饰符。实际上有两个占位符库。一个是基础,另一个是材料。建议我们使用Material,但可以随意使用您需要的任何东西。没有太大区别,API大多是等价的。在本博客中,我们使用的是Material。所以,让我们用这个命令导入它:implementationcom。google。accompanist:accompanistplaceholdermaterial:0。25。1
注意:检查是否有此依赖项的更新版本。
在继续MainScreen之前,让我们快速编辑MainViewModel。添加init和isLoadingStateFlow。此外,使用20个默认RowItem初始化项目。privatevalitemsMutableStateFlow(List(size20){RowItem()})valitemsitems。asStateFlow()privatevalisLoadingMutableStateFlow(true)valisLoadingisLoading。asStateFlow()init{viewModelScope。launch{delay(2000)items。valuegenerateItems()isLoading。valuefalse}}
我们的ViewModel现在看起来像这样:classMainViewModel:ViewModel(){privatevalisRefreshingMutableStateFlow(false)valisRefreshingisRefreshing。asStateFlow()privatevalcurrentTimeMutableStateFlow(Instant。now())valcurrentTimecurrentTime。asStateFlow()privatevalitemsMutableStateFlow(List(size20){RowItem()})valitemsitems。asStateFlow()privatevalisLoadingMutableStateFlow(true)valisLoadingisLoading。asStateFlow()init{viewModelScope。launch{delay(2000)items。valuegenerateItems()isLoading。valuefalse}}funrefresh()viewModelScope。launch{isRefreshing。update{true}SimulateAPIcalldelay(2000)currentTime。valueInstant。now()items。valuegenerateItems()isRefreshing。update{false}}privatefungenerateItems():ListRowItem{vallistmutableListOfRowItem()for(iin1until20){list。add(RowItem(rowImagerandomSampleImageUrl(),numberRandom。nextInt(1,1000)))}returnlist}privatefunrandomSampleImageUrl(seed:Int(0。。100000)。random(),width:Int300,height:Intwidth,):String{returnhttps:picsum。photosseedseedwidthheight}}dataclassRowItem(valrowImage:String,valnumber:Int1)
接下来是在我们的屏幕中收集isLoading,然后将其用作我们的占位符。我们正在向Item可组合项添加一个新参数childModifier:Modifier。Item(rowItemit,childModifierModifier。placeholder(visibleisLoading,highlightPlaceholderHighlight。fade(),))
如您所见,该库为占位符提供了一个修饰符。必需的参数是可见的:布尔值,它确定是否应显示占位符或内容。如果visible为真,那么将有一个占位符来填充应用它的可组合项的大小,而不是内容。
可选参数有:color:Color用于绘制占位符UI的颜色。如果提供了Color。Unspecified,则占位符将使用PlaceholderDefaults。colorshape:Shape占位符的所需形状。如果提供null,占位符将使用MaterialTheme。shapes中设置的小形状highlight:PlaceholderHighlight可选的高亮动画。有两个预先创建的占位符动画,淡入淡出和微光placeholderFadeTransitionSpec:ComposableTransition。Segment。()FiniteAnimationSpec将占位符淡入淡出屏幕时使用的转换规范。为过渡定义的布尔参数可见licontentFadeTransitionSpec:ComposableTransition。Segment。()FiniteAnimationSpec将内容淡入淡出屏幕时使用的转换规范。为过渡定义的布尔参数可见liul
我们的MainScreen现在看起来像这样:ComposablefunMainScreen(viewModel:MainViewModelviewModel()){valisRefreshingviewModel。isRefreshing。collectAsState()。valuevalisLoadingviewModel。isLoading。collectAsState()。valuevalcurrentTimeviewModel。currentTime。collectAsState()。valuevalitemsviewModel。items。collectAsState()。valuevalswipeRefreshStaterememberSwipeRefreshState(isRefreshingisRefreshing)SwipeRefresh(stateswipeRefreshState,onRefreshviewModel::refresh,modifierModifier。fillMaxSize()。padding(vertical32。dp,horizontal16。dp)){LazyColumn{item{Text(textWelcometoSwipetoRefresh!,styleMaterialTheme。typography。h5,modifierModifier。fillMaxWidth(),textAlignTextAlign。Center)Spacer(modifierModifier。height(32。dp))Text(textcurrentTime。toString(),modifierModifier。fillMaxWidth(),textAlignTextAlign。End)Spacer(modifierModifier。height(8。dp))}items(items){Item(rowItemit,childModifierModifier。placeholder(visibleisLoading,highlightPlaceholderHighlight。fade(),))}}}}ComposablefunItem(rowItem:RowItem,childModifier:ModifierModifier,){Card(modifierModifier。fillMaxWidth()。padding(vertical8。dp),elevation4。dp){Row(modifierModifier。fillMaxWidth()。padding(16。dp),verticalAlignmentAlignment。CenterVertically,){Image(painterrememberAsyncImagePainter(rowItem。rowImage),contentDescriptionrowItem。number。toString(),modifierchildModifier。size(64。dp))Spacer(modifierModifier。width(16。dp))Text(textNumber:{rowItem。number},modifierchildModifier。fillMaxWidth())}}}
就这样。我希望你喜欢它。
关注七爪网,获取更多APP小程序网站源码资源!