Jetpack Compose中的下拉刷新及加载更多

前言

Jetpack Compose光下拉刷新,官方就提供了三种不同的方式,使用的依赖也不相同,特别的混乱。

所以在网络上看到的示例可能找不到依赖就是这个原因。

其中

  • swiperefresh 被废弃了

  • PullToRefreshBox还处于实验阶段

也就是说只有前两种可以使用,如果不嫌弃代码中有废弃红线的标记,可以使用第一种,要么使用第二种。

Compose Material 3

最新版本是1.3.2,本文使用的是1.3.0

https://developer.android.google.cn/jetpack/androidx/releases/compose-material3?authuser=002&hl=zh-cn

下拉刷新

swiperefresh

这个已经废弃,不过依旧能用。

导入

1
implementation("com.google.accompanist:accompanist-swiperefresh:0.30.1")

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import android.util.Log
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
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.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@Preview
@Composable
fun LazyListExample() {
val coroutineScope = rememberCoroutineScope()
var isRefreshing by remember {
mutableStateOf(false)
}
SwipeRefresh(state = rememberSwipeRefreshState(isRefreshing), modifier = Modifier
.fillMaxWidth()
.height(200.dp), onRefresh = {
isRefreshing = true
// 在协程作用域中启动异步任务
coroutineScope.launch {
// 执行异步操作,例如网络请求或数据库查询
Log.i("刷新", "")
delay(3000)
isRefreshing = false
}
}) {
//布局
LazyColumn(Modifier.fillMaxSize()) {
items(30) { index ->
Text(text = index.toString())
}
}
}
}

PullToRefreshBox

这个还是实验API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import android.util.Log
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PullToRefreshDemo01() {
var isRefreshing by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val onRefresh: () -> Unit = {
Log.i("PullToRefreshBox", "isRefreshing: ")
isRefreshing = true
coroutineScope.launch {
delay(1500)
isRefreshing = false
}
}

PullToRefreshBox(
isRefreshing = isRefreshing,
onRefresh = onRefresh,
) {
// 内部
MyList(mutableListOf("1", "2", "3"))
}
}

@Composable
private fun MyList(mList: List<String>) {
LazyColumn(Modifier.fillMaxSize()) {
items(mList.size) {
ListItem(mList[it])
}
}
}

@Composable
private fun ListItem(text: String) {
// 构建列表项的 UI
Text(text = text)
}

加载更多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Composable
private fun MyList(mList: List<String>) {
val listState = rememberLazyListState()
val isScrolledToBottom by remember(listState) {
derivedStateOf {
// 判断是否滚动到了底部
listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index == mList.size - 1
}
}

// 根据是否滚动到底部执行相应的操作
if (isScrolledToBottom) {
// 滚动到了底部
Log.i("滚动", "滚动到了底部")
}

LazyColumn(Modifier.fillMaxSize(), state = listState) {
items(mList.size) {
ListItem(mList[it])
}
}
}

@Composable
private fun ListItem(text: String) {
// 构建列表项的 UI
Text(text = text)
}