一、 创建Activity Empty Compose模块
在Android Studio中创建一个新的项目,选择一个Empty Compose Activity,如下图所示:
二、搭建Scaffold脚手架主结构
/**
* Main activity
* 定义主活动
* @constructor Create empty Main activity
*/
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Ch04_ComposeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
mainScreen()
}
}
}
}
}//end MainActivity
/**
* Main screen
* 定义主界面的脚手架框架
*/
@Composable
fun mainScreen(){
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState,
//定义头部
topBar={
},
//定义侧滑内容
drawerContent = {
},
//定义中心区内容,实现界面的切换
content={
},
//定义底部的导航内容
bottomBar = {
},
//定义悬浮按钮
floatingActionButton={
}
)//end Scaffold
}
在主活动MainActivity中调用脚手架主框架
三、定义需要切换的三个界面:HomeScreen、SettingScreen、HelpScreen
显示效果如图所示:
/** 定义首页界面*/
@Preview
@Composable
fun HomeScreen(){
Column(modifier= Modifier
.fillMaxSize()
.padding(10.dp)
.background(colorResource(id = R.color.teal_200)),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
content = {
Text(text="首页界面",color=Color.White,
fontSize=36.sp, fontWeight = FontWeight.ExtraBold)
})
}
/**定义配置界面*/
@Preview
@Composable
fun SettingScreen(){
Column(
content = {
Text("配置界面",
fontSize=36.sp,
color = Color.White)
},
modifier = Modifier
.fillMaxSize()
.background(colorResource(R.color.teal_200)),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
)
}
/**定义帮助界面*/
@Preview
@Composable
fun HelpScreen(){
Column(modifier= Modifier.fillMaxSize()
.background(colorResource(id = R.color.teal_200)),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally){
Text("帮助界面",color= Color.White,fontSize=36.sp)
}
}
四、将切换屏幕界面定义在密封类中
/**
* 定义要切换界面的密封类
* @property route String
* @property title String
* @property screenToLoad [@androidx.compose.runtime.Composable] Function0<Unit>
* @constructor
*/
sealed class Screens(val route:String,val title:String,
val screenToLoad:@Composable ()->Unit){
object Home:Screens("home","首页", {
HomeScreen()
})
object Setting:Screens("setting","配置页面",{
SettingScreen()
})
object Help:Screens("help","帮助页面",{
HelpScreen()
})
}
定义保存屏幕界面的列表中
//定义要切换的界面列表
val screens = listOf<Screens>(Screens.Home,Screens.Setting,Screens.Help)
五、创建侧滑菜单的导航
创建侧滑菜单,显示效果如下所示:
(1)定义侧滑菜单的顶部内容
/**
* Top bar view
* 定义头部
*/
@Preview
@Composable
fun TopBarView(){
Box(modifier= Modifier
.fillMaxWidth()
.wrapContentHeight()
.background(color = colorResource(id = R.color.purple_200))){
Row(modifier= Modifier
.fillMaxWidth()
.padding(5.dp)){
Column{
Image(painter=painterResource(id = R.mipmap.boy),
contentDescription = "logo图标",
modifier= Modifier .width(dimensionResource(id = R.dimen.image_width))
.height(60.dp)
.clip(shape = CircleShape)
.background(Color.Black))
}//end Column
Column{
Text(stringResource(id = R.string.title_robot))
Text(stringResource(id = R.string.title_introduction))
}
}//end Column
}
}
(2)定义侧滑菜单
/**
* 定义侧滑的下面的菜单
* @param selectedScreen Screens 要选择切换的界面
* @param onMenuSelected Function1<[@kotlin.ParameterName] Screens, Unit>? 要处理的切换动作,默认为空
*/
@Composable
fun DrawerMenuView(selectedScreen:Screens,
onMenuSelected:((screen:Screens)->Unit)?=null){
Column(modifier=Modifier.fillMaxWidth()){
//对每个界面进行遍历访问
screens.forEach{it:Screens->
Row(
content = {
Text(text = it.title,
fontSize=20.sp, fontWeight = FontWeight.Bold,
color = if(it.route==selectedScreen.route) colorResource(id = R.color.purple_500) else colorResource(id = R.color.teal_700))
},
modifier = Modifier.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
.clickable {//处理点击动作
onMenuSelected?.invoke(it)
}
)//end Row
}
}
}
(3)组合两部分的内容到脚手架主框架中。
在脚手架中增加侧滑菜单的处理
/**
* Main screen
* 定义主界面的脚手架框架
*/
@Composable
fun mainScreen(){
//脚手架的状态
val scaffoldState = rememberScaffoldState()
//协程的范围
val scope = rememberCoroutineScope()
//当前的屏幕
Val currentScreen:MutableState<Screens>=
remember{ mutableStateOf(Screens.Home) }
Scaffold(scaffoldState = scaffoldState,
//定义头部
topBar={
},
//定义侧滑内容
drawerContent = {
TopBarView()
**DrawerMenuView**(selectedScreen = currentScreen.value){screen->
scope.launch {
//关闭侧滑菜单
**scaffoldState.drawerState.close()**
}
//将选择的菜单设置为当前菜单
currentScreen.value = screen
}
},
.......
)//end Scaffold
}
六、创建应用头部的导航
/**
* 定义应用头部内容
* 在头部定义一个导航菜单
* @param currentScreen Screens 当前屏幕界面
* @param scaffoldState ScaffoldState 脚手架的状态
* @param scope CoroutineScope 协程的范围
*/
@Composable
fun TopAppView(currentScreen:Screens,
scaffoldState:ScaffoldState,scope:CoroutineScope){
TopAppBar(title = {//标题
Text(currentScreen.title)
},
navigationIcon = {//导航图标
IconButton(onClick = {
scope.launch {
scaffoldState.drawerState.open()//打开侧滑菜单
}//end scope.launch
}){
Icon(Icons.Filled.Menu,"Home导航图标") //定义图标
}
},//end navigationIcon
backgroundColor = Color.Blue,
contentColor =Color.White
)
}
说明:
(1) scaffoldState:ScaffoldState,scope:CoroutineScope必须与脚手架中使用的scaffoldState对象和scope协程对象已知,否则无法控制导航的实现;
(2) currentScreen是正在显示的屏幕界面,用于头部标题的显示
(3) 定义TopAppBar来定义类似ActionBar的头部动作条。
修改MainActivity.kt中定义的脚手架,增加TopBar的功能
/**
* Main screen
* 定义主界面的脚手架框架
*/
@Composable
fun mainScreen(){
//脚手架的状态
val scaffoldState = rememberScaffoldState()
//协程的范围
val scope = rememberCoroutineScope()
//当前的屏幕
val currentScreen: MutableState<Screens> = remember{ mutableStateOf(Screens.Home) }
Scaffold(scaffoldState = scaffoldState,
//定义头部
topBar={
TopAppView(currentScreen = currentScreen.value,
scaffoldState =scaffoldState , scope =scope )
},
......
)//end Scaffold
}
七、创建应用底部的导航
运行效果如下所示:
(1) 定义底部导航菜单项单项实体类
/**
* 定义底部的菜单单项
* @property label String 菜单项
* @property icon ImageVector 菜单的图标
* @property route String 菜单的路线
* @property screen Screens 菜单选择对应的界面
* @constructor
*/
data class BottomMenuItem(val label:String,
val icon: ImageVector,
val route:String,
val screen:Screens)
(2) 定义底部导航栏的内容
/**
* 定义应用底部的视图
*接收从外部传递的要显示的当前界面
*/
@Composable
fun BottomAppView(currentScreen:MutableState<Screens>){
//定义底部菜单项列表
val menuItems = listOf<BottomMenuItem>(
BottomMenuItem("首页", Icons.Filled.Home,"home",Screens.Home),
BottomMenuItem("配置界面", Icons.Filled.Settings,"setting",Screens.Setting),
BottomMenuItem("帮助界面", Icons.Filled.Info,"help",Screens.Help)
)
BottomNavigation(backgroundColor = Color.Blue,
contentColor = Color.White, elevation = 5.dp) {
menuItems.forEach { menuItem ->
BottomNavigationItem(//定义单项
//选择菜单项的状态
selected = menuItem.route == currentScreen.value.route,
//图标
icon={
Icon(imageVector = menuItem.icon,
contentDescription = menuItem.label)
},
//文本
label={
Text(menuItem.label)
},
//点击动作处理
onClick = {
currentScreen.value = menuItem.screen
})
}//end forEach
}
}
(3) 底部导航栏加入到脚手架中,并实现底部导航
在MainActivity.kt中的脚手架中,增加底部导航栏的处理
@Composable
fun mainScreen(){
//脚手架的状态
val scaffoldState = rememberScaffoldState()
//协程的范围
val scope = rememberCoroutineScope()
//当前的屏幕
val currentScreen: MutableState<Screens> = remember{ mutableStateOf(Screens.Home) }
Scaffold(scaffoldState = scaffoldState,
.....
//定义底部的导航内容
bottomBar = {
**BottomAppView(currentScreen)**
}
.....
)//end Scaffold
}
八、脚手架增加浮动按钮返回首页的处理
@Composable
fun mainScreen(){
//脚手架的状态
val scaffoldState = rememberScaffoldState()
//协程的范围
val scope = rememberCoroutineScope()
//当前的屏幕
val currentScreen: MutableState<Screens> = remember{ mutableStateOf(Screens.Home) }
//当前上下文
val context = LocalContext.current
Scaffold(scaffoldState = scaffoldState,
......
floatingActionButton = {
FloatingActionButton(onClick = {
Toast.makeText(context,"返回首页",Toast.LENGTH_LONG).show()
currentScreen.value = Screens.Home
}){
Icon(Icons.Filled.Home, contentDescription = "返回首页")
}
}
)//end Scaffold
}
参考文献
(1)www.geeksforgeeks.org/bottom-navi…
(2)amryousef.me/side-drawer…
本文转自 blog.csdn.net/userhu2012/…,如有侵权,请联系删除。