Android Jetpack Compose - ModalNavigationDrawer、NavigationRail、PullToRefreshBox

一、ModalNavigationDrawer(抽屉式导航栏)

  1. 使用 drawerContent,提供 ModalDrawerSheet(提供抽屉式导航栏的内容)。可以通过从侧边滑动或点击按钮来打开抽屉式导航栏
kotlin 复制代码
var selectedItemIndex by remember { mutableStateOf(0) }

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("抽屉式导航栏", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Home, contentDescription = null) },
                label = { Text("Home") },
                selected = selectedItemIndex == 0,
                onClick = { selectedItemIndex = 0 }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Call, contentDescription = null) },
                label = { Text("Call") },
                selected = selectedItemIndex == 1,
                onClick = { selectedItemIndex = 1 }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Email, contentDescription = null) },
                label = { Text("Email") },
                selected = selectedItemIndex == 2,
                onClick = { selectedItemIndex = 2 }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Person, contentDescription = null) },
                label = { Text("Person") },
                selected = selectedItemIndex == 3,
                onClick = { selectedItemIndex = 3 }
            )
        }
    }
) {}
  1. 控制抽屉式导航栏的打开和关闭,使用 DrawerState,它提供了 open 与 close 方法
kotlin 复制代码
var selectedItemIndex by remember { mutableStateOf(0) }

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet {
            Text("抽屉式导航栏", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Home, contentDescription = null) },
                label = { Text("Home") },
                selected = selectedItemIndex == 0,
                onClick = {
                    selectedItemIndex = 0
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Call, contentDescription = null) },
                label = { Text("Call") },
                selected = selectedItemIndex == 1,
                onClick = {
                    selectedItemIndex = 1
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Email, contentDescription = null) },
                label = { Text("Email") },
                selected = selectedItemIndex == 2,
                onClick = {
                    selectedItemIndex = 2
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Person, contentDescription = null) },
                label = { Text("Person") },
                selected = selectedItemIndex == 3,
                onClick = {
                    selectedItemIndex = 3
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
        }
    }
) {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Button(
            onClick = {
                scope.launch {
                    drawerState.open()
                }
            }
        ) {
            Text("打开抽屉式导航栏")
        }
    }
}
kotlin 复制代码
var selectedItemIndex by remember { mutableStateOf(0) }

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    gesturesEnabled = false,
    drawerContent = {
        ModalDrawerSheet {
            Text("抽屉式导航栏", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Home, contentDescription = null) },
                label = { Text("Home") },
                selected = selectedItemIndex == 0,
                onClick = {
                    selectedItemIndex = 0
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Call, contentDescription = null) },
                label = { Text("Call") },
                selected = selectedItemIndex == 1,
                onClick = {
                    selectedItemIndex = 1
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Email, contentDescription = null) },
                label = { Text("Email") },
                selected = selectedItemIndex == 2,
                onClick = {
                    selectedItemIndex = 2
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
            NavigationDrawerItem(
                icon = { Icon(Icons.Filled.Person, contentDescription = null) },
                label = { Text("Person") },
                selected = selectedItemIndex == 3,
                onClick = {
                    selectedItemIndex = 3
                    scope.launch {
                        drawerState.close()
                    }
                }
            )
        }
    }
) {
    Scaffold(
        topBar = {
            TopAppBar(
                colors = topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    IconButton(
                        onClick = {
                            scope.launch {
                                drawerState.open()
                            }
                        }
                    ) {
                        Icon(Icons.Default.MoreVert, contentDescription = "MoreVert")
                    }
                }
            )
        },
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
        ) {
            Text("内容区域")
        }
    }
}

二、NavigationRail(侧边导航栏)

kotlin 复制代码
var selectedItemIndex by remember { mutableStateOf(0) }

NavigationRail {
    NavigationRailItem(
        icon = { Icon(Icons.Filled.Home, contentDescription = null) },
        label = { Text("Home") },
        selected = selectedItemIndex == 0,
        onClick = { selectedItemIndex = 0 }
    )
    NavigationRailItem(
        icon = { Icon(Icons.Filled.Call, contentDescription = null) },
        label = { Text("Call") },
        selected = selectedItemIndex == 1,
        onClick = { selectedItemIndex = 1 }
    )
    NavigationRailItem(
        icon = { Icon(Icons.Filled.Email, contentDescription = null) },
        label = { Text("Email") },
        selected = selectedItemIndex == 2,
        onClick = { selectedItemIndex = 2 }
    )
    NavigationRailItem(
        icon = { Icon(Icons.Filled.Person, contentDescription = null) },
        label = { Text("Person") },
        selected = selectedItemIndex == 3,
        onClick = { selectedItemIndex = 3 }
    )
}
kotlin 复制代码
var selectedItemIndex by remember { mutableStateOf(0) }

Row(
    modifier = Modifier.fillMaxSize()
) {
    NavigationRail {
        NavigationRailItem(
            icon = { Icon(Icons.Filled.Home, contentDescription = null) },
            label = { Text("Home") },
            selected = selectedItemIndex == 0,
            onClick = { selectedItemIndex = 0 }
        )
        NavigationRailItem(
            icon = { Icon(Icons.Filled.Call, contentDescription = null) },
            label = { Text("Call") },
            selected = selectedItemIndex == 1,
            onClick = { selectedItemIndex = 1 }
        )
        NavigationRailItem(
            icon = { Icon(Icons.Filled.Email, contentDescription = null) },
            label = { Text("Email") },
            selected = selectedItemIndex == 2,
            onClick = { selectedItemIndex = 2 }
        )
        NavigationRailItem(
            icon = { Icon(Icons.Filled.Person, contentDescription = null) },
            label = { Text("Person") },
            selected = selectedItemIndex == 3,
            onClick = { selectedItemIndex = 3 }
        )
    }

    Column(
        modifier = Modifier
            .fillMaxHeight()
            .weight(1f),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text("内容区域")
    }
}
kotlin 复制代码
data class NavItem(
    val title: String,
    val icon: ImageVector,
)

val navItems = listOf(
    NavItem("Home", Icons.Filled.Home),
    NavItem("Call", Icons.Filled.Call),
    NavItem("Email", Icons.Filled.Email),
    NavItem("Person", Icons.Filled.Person)
)

var selectedItemIndex by remember { mutableStateOf(0) }

Row(
    modifier = Modifier.fillMaxSize()
) {
    NavigationRail {
        navItems.forEachIndexed { index, item ->
            NavigationRailItem(
                icon = { Icon(item.icon, contentDescription = item.title) },
                label = { Text(item.title) },
                selected = selectedItemIndex == index,
                onClick = { selectedItemIndex = index },
            )
        }
    }

    Column(
        modifier = Modifier
            .fillMaxHeight()
            .weight(1f),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        when (selectedItemIndex) {
            0 -> Text("Home")
            1 -> Text("Call")
            2 -> Text("Email")
            3 -> Text("Person")
        }
    }
}

三、PullToRefreshBox(下拉刷新)

1、基本介绍
  • PullToRefreshBox 组件用于实现下拉刷新,该组件可以包裹可滚动内容,关键参数如下
  1. isRefreshing:指示刷新操作是否正在进行

  2. onRefresh:当发起刷新时执行的函数

2、演示
kotlin 复制代码
var items by remember { mutableStateOf(List(5) { "第 ${it + 1} 项" }) }
val scope = rememberCoroutineScope()

var isRefreshing by remember { mutableStateOf(false) }

PullToRefreshBox(
    modifier = Modifier.fillMaxSize(),
    isRefreshing = isRefreshing,
    onRefresh = {
        isRefreshing = true
        scope.launch {
            delay(1500)
            items = List((1..10).random()) { "新数据 ${it + 1}" }
            isRefreshing = false
        }
    }
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        items(items) { item ->
            Card(
                modifier = Modifier.fillMaxWidth(),
                colors = CardDefaults.cardColors(
                    containerColor = MaterialTheme.colorScheme.surfaceVariant
                )
            ) {
                Text(
                    text = item,
                    modifier = Modifier.padding(16.dp),
                    style = MaterialTheme.typography.bodyLarge
                )
            }
        }
    }
}
相关推荐
nanxun8863 小时前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103516 小时前
Day01 | Java 基础(Java SE)
java
行者全栈架构师8 小时前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师12 小时前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_012 小时前
mac(m5)平台编译openjdk
java
唐青枫1 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马1 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261351 天前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
逐光老顽童1 天前
Java 与 Kotlin 混合开发避坑指南:30 个真实案例实录
android·kotlin
用户3721574261351 天前
Java 打印 Word 文档:从基础打印到高级设置
java