📌  相关文章
📜  使用 Jetpack Compose 在 Android 中搭建脚手架

📅  最后修改于: 2022-05-13 01:55:44.166000             🧑  作者: Mango

使用 Jetpack Compose 在 Android 中搭建脚手架

有很多应用程序包含 TopAppBar、Drawer、Floating Action Button、BottomAppBar(以底部导航的形式)、Snackbar。虽然您可以在一个应用程序中单独设置所有这些,但需要进行大量设置。 Jetpack Compose 提供了Scaffold Composable ,可以节省大量时间。它就像一个预先构建的模板。在本文中,我们将看到如何使用 Jetpack Compose 在 android 中设置 Scaffold。我们将构建一个基本的应用程序来演示可组合的 Scaffold,这是一个展示该应用程序的视频。

先决条件:

  • 对 Kotlin 的了解。
  • Jetpack Compose 的知识。

分步实施

第 1 步:创建 TopAppBar

打开MainActivity.kt并创建一个 TopBar Composable函数,它将是我们在 Scaffold 中的 TopAppBar 的包装器。

Kotlin
// A function which will receive a 
// callback to trigger to opening the drawer
@Composable
fun TopBar(onMenuClicked: () -> Unit) {
  
    // TopAppBar Composable
    TopAppBar(
        // Provide Title
        title = {
            Text(text = "Scaffold||GFG", color = Color.White)
        },
        // Provide the navigation Icon (Icon on the left to toggle drawer)
        navigationIcon = {
            Icon(
                imageVector = Icons.Default.Menu,
                contentDescription = "Menu",
                  
                // When clicked trigger onClick 
                // Callback to trigger drawer open
                modifier = Modifier.clickable(onClick = onMenuClicked), 
                tint = Color.White
            )
        },
        // background color of topAppBar
        backgroundColor = Color(0xFF0F9D58)
    )
}


Kotlin
@Composable
fun BottomBar() {
    // BottomAppBar Composable
    BottomAppBar(
        backgroundColor = Color(0xFF0F9D58)
    ) {
        Text(text = "Bottom App Bar", color = Color.White)
    }
}


Kotlin
@Composable
fun Drawer() {
    // Column Composable
    Column(
        Modifier
            .background(Color.White)
            .fillMaxSize()
    ) {
        // Repeat is a loop which
        // takes count as argument 
        repeat(5) { item ->
            Text(text = "Item number $item", modifier = Modifier.padding(8.dp), color = Color.Black)
        }
    }
}


Kotlin
@Composable
fun Body() {
    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Text(text = "Body Content", color = Color(0xFF0F9D58))
    }
}


Kotlin
@Composable
fun ScaffoldExample() {
  
    // create a scaffold state, set it to close by default
    val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
  
    // Create a coroutine scope. Opening of 
    // Drawer and snackbar should happen in
    // background thread without blocking main thread
    val coroutineScope = rememberCoroutineScope()
  
    // Scaffold Composable
    Scaffold(
        
        // pass the scaffold state
        scaffoldState = scaffoldState,
        
        // pass the topbar we created
        topBar = {
            TopBar(
                // When menu is clicked open the
                // drawer in coroutine scope
                onMenuClicked = {
                    coroutineScope.launch {
                        // to close use -> scaffoldState.drawerState.close()
                        scaffoldState.drawerState.open()
                    }
                })
        },
        
        // pass the bottomBar
        // we created
        bottomBar = { BottomBar() },
        
        // Pass the body in
        // content parameter
        content = {
            Body()
        },
        
        // pass the drawer
        drawerContent = {
            Drawer()
        },
  
        floatingActionButton = {
            // Create a floating action button in 
            // floatingActionButton parameter of scaffold
            FloatingActionButton(
  
                onClick = {
                    // When clicked open Snackbar
                    coroutineScope.launch {
                        when (scaffoldState.snackbarHostState.showSnackbar(
                            // Message In the snackbar
                            message = "Snack Bar", 
                            actionLabel = "Dismiss"
                        )) {
                            SnackbarResult.Dismissed -> {
                                // do something when 
                               // snack bar is dismissed
                            }
  
                            SnackbarResult.ActionPerformed -> {
                            // when it appears
                            }
                        }
                    }
                }) {
                // Simple Text inside FAB
                Text(text = "X")
            }
        }
    )
}


Kotlin
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { 
            Surface(color = Color.White) {
                // Scaffold we created
                ScaffoldExample()
            }         
        }
    }
}


Kotlin
package com.gfg.scaffoldjetpackcompose
  
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
  
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Surface(color = Color.White) {
                // Scaffold we created
                ScaffoldExample()
            }
        }
    }
}
  
@Composable
fun ScaffoldExample() {
  
    // create a scaffold state, set it to close by default
    val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
  
    // Create a coroutine scope. Opening of Drawer
    // and snackbar should happen in background 
    // thread without blocking main thread
    val coroutineScope = rememberCoroutineScope()
  
    // Scaffold Composable
    Scaffold(
        
        // pass the scaffold state
        scaffoldState = scaffoldState,
        
        // pass the topbar we created
        topBar = {
            TopBar(
                // When menu is clicked open the
                // drawer in coroutine scope
                onMenuClicked = {
                    coroutineScope.launch {
                        // to close use -> scaffoldState.drawerState.close()
                        scaffoldState.drawerState.open()
                    }
                })
        },
        
        // pass the bottomBar we created
        bottomBar = { BottomBar() },
        
        // Pass the body in
        // content parameter
        content = {
            Body()
        },
        
        // pass the drawer
        drawerContent = {
            Drawer()
        },
  
        floatingActionButton = {
            // Create a floating action button in
            // floatingActionButton parameter of scaffold
            FloatingActionButton(
                onClick = {
                    // When clicked open Snackbar
                    coroutineScope.launch {
                        when (scaffoldState.snackbarHostState.showSnackbar(
                            // Message In the snackbar
                            message = "Snack Bar", 
                            actionLabel = "Dismiss"
                        )) {
                            SnackbarResult.Dismissed -> {
                                // do something when 
                                // snack bar is dismissed
                            }
  
                            SnackbarResult.ActionPerformed -> {
                            // when it appears
                            }
  
                        }
                    }
                }) {
                // Simple Text inside FAB
                Text(text = "X")
            }
        }
    )
}
  
// A function which will receive a 
// callback to trigger to opening the drawer
@Composable
fun TopBar(onMenuClicked: () -> Unit) {
    // TopAppBar Composable
    TopAppBar(
        // Provide Title
        title = {
            Text(text = "Scaffold||GFG", color = Color.White)
        },
        // Provide the navigation Icon ( Icon on the left to toggle drawer)
        navigationIcon = {
            Icon(
                imageVector = Icons.Default.Menu,
                contentDescription = "Menu",
  
                   // When clicked trigger onClick 
                  // Callback to trigger drawer open
                modifier = Modifier.clickable(onClick = onMenuClicked),
                tint = Color.White
            )
        },
        // background color of topAppBar
        backgroundColor = Color(0xFF0F9D58)
    )
}
  
@Composable
fun BottomBar() {
    // BottomAppBar Composable
    BottomAppBar(
        backgroundColor = Color(0xFF0F9D58)
    ) {
        Text(text = "Bottom App Bar", color = Color.White)
    }
}
  
@Composable
fun Body() {
    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Text(text = "Body Content", color = Color(0xFF0F9D58))
    }
}
  
  
@Composable
fun Drawer() {
    // Column Composable
    Column(
        Modifier
            .background(Color.White)
            .fillMaxSize()
    ) {
        // Repeat is a loop which
        // takes count as argument
        repeat(5) { item ->
            Text(text = "Item number $item", modifier = Modifier.padding(8.dp), color = Color.Black)
        }
    }
}


第二步:创建BottomAppBar

打开MainActivity.kt并创建一个BottomBar Composable。在我们的应用程序中,这将是一个简单的直接前进。

科特林

@Composable
fun BottomBar() {
    // BottomAppBar Composable
    BottomAppBar(
        backgroundColor = Color(0xFF0F9D58)
    ) {
        Text(text = "Bottom App Bar", color = Color.White)
    }
}

第 3 步:创建抽屉内容

打开MainActivity.kt并创建一个可组合的 Drawer,它将成为我们 Scaffold 中的 drawer。

科特林

@Composable
fun Drawer() {
    // Column Composable
    Column(
        Modifier
            .background(Color.White)
            .fillMaxSize()
    ) {
        // Repeat is a loop which
        // takes count as argument 
        repeat(5) { item ->
            Text(text = "Item number $item", modifier = Modifier.padding(8.dp), color = Color.Black)
        }
    }
}

第 4 步:创建 Scaffold 的主体部分

创建另一个可组合的函数体。它将是我们应用程序中可组合的简单文本。在其他应用程序中实现它时,请务必对其进行自定义。



科特林

@Composable
fun Body() {
    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Text(text = "Body Content", color = Color(0xFF0F9D58))
    }
}

由于我们需要的所有组件都已完成,让我们开始处理 Scaffold Part。

第 5 步:使用 Scaffold

由于我们已经创建了所有组件,因此 Scaffold 代码将非常简单且不言自明。

科特林

@Composable
fun ScaffoldExample() {
  
    // create a scaffold state, set it to close by default
    val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
  
    // Create a coroutine scope. Opening of 
    // Drawer and snackbar should happen in
    // background thread without blocking main thread
    val coroutineScope = rememberCoroutineScope()
  
    // Scaffold Composable
    Scaffold(
        
        // pass the scaffold state
        scaffoldState = scaffoldState,
        
        // pass the topbar we created
        topBar = {
            TopBar(
                // When menu is clicked open the
                // drawer in coroutine scope
                onMenuClicked = {
                    coroutineScope.launch {
                        // to close use -> scaffoldState.drawerState.close()
                        scaffoldState.drawerState.open()
                    }
                })
        },
        
        // pass the bottomBar
        // we created
        bottomBar = { BottomBar() },
        
        // Pass the body in
        // content parameter
        content = {
            Body()
        },
        
        // pass the drawer
        drawerContent = {
            Drawer()
        },
  
        floatingActionButton = {
            // Create a floating action button in 
            // floatingActionButton parameter of scaffold
            FloatingActionButton(
  
                onClick = {
                    // When clicked open Snackbar
                    coroutineScope.launch {
                        when (scaffoldState.snackbarHostState.showSnackbar(
                            // Message In the snackbar
                            message = "Snack Bar", 
                            actionLabel = "Dismiss"
                        )) {
                            SnackbarResult.Dismissed -> {
                                // do something when 
                               // snack bar is dismissed
                            }
  
                            SnackbarResult.ActionPerformed -> {
                            // when it appears
                            }
                        }
                    }
                }) {
                // Simple Text inside FAB
                Text(text = "X")
            }
        }
    )
}

现在从Mainactivity类中的 setContent 调用这个可组合

科特林

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { 
            Surface(color = Color.White) {
                // Scaffold we created
                ScaffoldExample()
            }         
        }
    }
}

现在运行应用程序并查看它的运行情况。

完整代码:

科特林

package com.gfg.scaffoldjetpackcompose
  
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
  
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Surface(color = Color.White) {
                // Scaffold we created
                ScaffoldExample()
            }
        }
    }
}
  
@Composable
fun ScaffoldExample() {
  
    // create a scaffold state, set it to close by default
    val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
  
    // Create a coroutine scope. Opening of Drawer
    // and snackbar should happen in background 
    // thread without blocking main thread
    val coroutineScope = rememberCoroutineScope()
  
    // Scaffold Composable
    Scaffold(
        
        // pass the scaffold state
        scaffoldState = scaffoldState,
        
        // pass the topbar we created
        topBar = {
            TopBar(
                // When menu is clicked open the
                // drawer in coroutine scope
                onMenuClicked = {
                    coroutineScope.launch {
                        // to close use -> scaffoldState.drawerState.close()
                        scaffoldState.drawerState.open()
                    }
                })
        },
        
        // pass the bottomBar we created
        bottomBar = { BottomBar() },
        
        // Pass the body in
        // content parameter
        content = {
            Body()
        },
        
        // pass the drawer
        drawerContent = {
            Drawer()
        },
  
        floatingActionButton = {
            // Create a floating action button in
            // floatingActionButton parameter of scaffold
            FloatingActionButton(
                onClick = {
                    // When clicked open Snackbar
                    coroutineScope.launch {
                        when (scaffoldState.snackbarHostState.showSnackbar(
                            // Message In the snackbar
                            message = "Snack Bar", 
                            actionLabel = "Dismiss"
                        )) {
                            SnackbarResult.Dismissed -> {
                                // do something when 
                                // snack bar is dismissed
                            }
  
                            SnackbarResult.ActionPerformed -> {
                            // when it appears
                            }
  
                        }
                    }
                }) {
                // Simple Text inside FAB
                Text(text = "X")
            }
        }
    )
}
  
// A function which will receive a 
// callback to trigger to opening the drawer
@Composable
fun TopBar(onMenuClicked: () -> Unit) {
    // TopAppBar Composable
    TopAppBar(
        // Provide Title
        title = {
            Text(text = "Scaffold||GFG", color = Color.White)
        },
        // Provide the navigation Icon ( Icon on the left to toggle drawer)
        navigationIcon = {
            Icon(
                imageVector = Icons.Default.Menu,
                contentDescription = "Menu",
  
                   // When clicked trigger onClick 
                  // Callback to trigger drawer open
                modifier = Modifier.clickable(onClick = onMenuClicked),
                tint = Color.White
            )
        },
        // background color of topAppBar
        backgroundColor = Color(0xFF0F9D58)
    )
}
  
@Composable
fun BottomBar() {
    // BottomAppBar Composable
    BottomAppBar(
        backgroundColor = Color(0xFF0F9D58)
    ) {
        Text(text = "Bottom App Bar", color = Color.White)
    }
}
  
@Composable
fun Body() {
    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Text(text = "Body Content", color = Color(0xFF0F9D58))
    }
}
  
  
@Composable
fun Drawer() {
    // Column Composable
    Column(
        Modifier
            .background(Color.White)
            .fillMaxSize()
    ) {
        // Repeat is a loop which
        // takes count as argument
        repeat(5) { item ->
            Text(text = "Item number $item", modifier = Modifier.padding(8.dp), color = Color.Black)
        }
    }
}

输出:

从 GitHub 获取完整的项目。

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!