Android 项目 tabBar 配置:仿微信

Android 项目 tabBar 配置:仿微信

源码

配置

MainActivity

package cn.com.xuxiaowei

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.Scaffold
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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.unit.dp
import cn.com.xuxiaowei.ui.page.FavoritesPage
import cn.com.xuxiaowei.ui.page.HomePage
import cn.com.xuxiaowei.ui.page.ProfilePage
import cn.com.xuxiaowei.ui.theme.NavigationActive
import cn.com.xuxiaowei.ui.theme.NavigationInactive
import cn.com.xuxiaowei.ui.theme.XuxiaoweiTheme
import cn.com.xuxiaowei.utils.FileLogger

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FileLogger.log(this, "startup", "MainActivity", "onCreate")
        enableEdgeToEdge()
        setContent {
            XuxiaoweiTheme {
                XuxiaoweiApp()
            }
        }
    }
}

@PreviewScreenSizes
@Composable
fun XuxiaoweiApp() {
    val context = LocalContext.current
    var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }

    Scaffold(
        bottomBar = {
            val bottomPadding =
                WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
            NavigationBar(modifier = Modifier.height(54.dp + bottomPadding)) {
                AppDestinations.entries.forEach {
                    val isSelected = it == currentDestination
                    Column(
                        modifier =
                            Modifier.weight(1f)
                                .fillMaxHeight()
                                .clickable(
                                    interactionSource = remember { MutableInteractionSource() },
                                    indication = null,
                                    onClick = {
                                        FileLogger.log(
                                            context,
                                            "app",
                                            "XuxiaoweiApp",
                                            "Switching to: ${it.label}",
                                        )
                                        currentDestination = it
                                    },
                                ),
                        horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.Center,
                    ) {
                        Icon(
                            it.icon,
                            contentDescription = it.label,
                            tint = if (isSelected) NavigationActive else NavigationInactive,
                        )
                        Text(
                            it.label,
                            color = if (isSelected) NavigationActive else NavigationInactive,
                            style = MaterialTheme.typography.labelSmall,
                        )
                    }
                }
            }
        }
    ) { innerPadding ->
        val contentModifier = Modifier.fillMaxSize().padding(innerPadding)
        when (currentDestination) {
            AppDestinations.HOME -> HomePage(modifier = contentModifier)
            AppDestinations.FAVORITES -> FavoritesPage(modifier = contentModifier)
            AppDestinations.PROFILE -> ProfilePage(modifier = contentModifier)
        }
    }
}

enum class AppDestinations(
    val label: String,
    val icon: ImageVector,
) {
    HOME("Home", Icons.Default.Home),
    FAVORITES("Favorites", Icons.Default.Favorite),
    PROFILE("Profile", Icons.Default.AccountBox),
}

HomePage

package cn.com.xuxiaowei.ui.page

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun HomePage(modifier: Modifier = Modifier) {
    Text(text = "Home 页面", modifier = modifier)
}

FavoritesPage

package cn.com.xuxiaowei.ui.page

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun FavoritesPage(modifier: Modifier = Modifier) {
    Text(text = "Favorites 页面", modifier = modifier)
}

ProfilePage

package cn.com.xuxiaowei.ui.page

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun ProfilePage(modifier: Modifier = Modifier) {
    Text(text = "Profile 页面", modifier = modifier)
}

Color

val NavigationActive = Color(0xFF07C160)
val NavigationInactive = Color(0xFF444444)

效果