前言
- 项目地址:https://github.com/Peakmain/ComposeProject
- 网上现在有不少jetpack compose的文章和教程,但是实战项目不多。
- 项目接口基于玩Android,这里也非常感谢大佬提供的免费接口
建议
先学习kotlin语言,最好有Android App开发经验
项目结构
新建项目New Project->选择 Empty Compose Activity
填写必要信息,完成项目创建
Compose和Android View的区别
Android View | compose |
---|---|
Button | Button |
TextView | Text |
EditText | TextField |
ImageView | Image |
LinearLayout(horizontally) | Row |
LinearLayout(vertically) | Column |
FrameLayout | Box |
RecyclerView | LazyColumn |
RecyclerView(horizontally) | LazyRow |
Snackbar | Snackbar |
一些基础知识
Scaffold
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
isFloatingActionButtonDocked: Boolean = false,
drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
drawerGesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
drawerScrimColor: Color = DrawerDefaults.scrimColor,
backgroundColor: Color = MaterialTheme.colors.background,
contentColor: Color = contentColorFor(backgroundColor),
content: @Composable (PaddingValues) -> Unit
)
Scaffold主要用于快速搭建一个项目的结构,包含:
- topBar:通常是TopAppBar
- bottomBar 通常是一个 BottomNavigation,里面每个item是BottomNavigationItem
- floatingActionButton 悬浮按钮
- floatingActionButtonPosition 悬浮按钮位置
- isFloatingActionButtonDocked 悬浮按钮是否贴到 bottomBar 上
- drawerContent 侧滑菜单
- content:内容区域
BottomNavigationItem
fun RowScope.BottomNavigationItem(
selected: Boolean,//是否被选中
onClick: () -> Unit,//点击事件
icon: @Composable () -> Unit,//icon图标
modifier: Modifier = Modifier,
enabled: Boolean = true,//是否可用
label: @Composable (() -> Unit)? = null,//这里就是文本
alwaysShowLabel: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
selectedContentColor: Color = LocalContentColor.current,
unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
)
- selected:是否被选中
- onClick:点击事件
- icon:Icon的图标
- modifier: Modifier
- enabled:是否可用
- label:这里就是文本内容区域
- selectedContentColor:选中时的颜色
- unselectedContentColor:未选中的颜色
状态
- 官方文档:https://developer.android.google.cn/jetpack/compose/state
状态和组合
由于 Compose 是声明式工具集,因此更新它的唯一方法是通过新参数调用同一可组合项。这些参数是界面状态的表现形式。每当状态更新时,都会发生重组。因此,TextField 不会像在基于 XML 的命令式视图中那样自动更新。可组合项必须明确获知新状态,才能相应地进行更新
@Composable
fun HelloContent() {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
OutlinedTextField(
value = "",
onValueChange = { },
label = { Text("Name") }
)
}
}
- OutlinedTextField与 TextField 只是样式不同
- 如果运行此代码,您将不会看到任何反应。这是因为,TextField 不会自行更新,但会在其 value 参数更改时更新。
Compose中的状态
- Composable中可以使用remember来记住单个对象。
- 系统会在初始化由 remember计算的值存储在Composable中,并在重组的时候返回存储的值
- remember既可以存储可变对象,也可以存储不可变对象。
注意:remember 会将对象存储在组合中,当调用 remember 的可组合项从组合中移除后,它会忘记该对象。
mutableStateOf 会创建可观察的 MutableState
interface MutableState : State {
override var value: T
}
value 如有任何更改,系统会安排重组读取 value 的所有可组合函数。
在可组合项中声明 MutableState 对象的方法有三种:
- val mutableState = remember { mutableStateOf(default) }
- var value by remember { mutableStateOf(default) }
- val (value, setValue) = remember { mutableStateOf(default) }
这些声明是等效的,以语法糖的形式针对状态的不同用法提供。您选择的声明应该能够在您编写的可组合项中生成可读性最高的代码。
所以上面代码的解决办法
@Composable
fun HelloContent() {
Column(modifier = Modifier.padding(16.dp)) {
var name by remember { mutableStateOf("") }//定义状态
if (name.isNotEmpty()) {
Text(
text = "Hello, $name!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
}
OutlinedTextField(
value = name,//要显示的当前值
onValueChange = { name = it },//请求更改值的事件,其中 T 是建议的新值
label = { Text("Name") }
)
}
}
小技巧:Compose的代码模板
在搭建基本框架之前,我们先来定义一个模板,方便大家开发(我的是Mac电脑)
-
1、Android Studio-> Preferences->Editor->File and Code Templates
2、点击➕号
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end
#parse("File Header.java")
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
#if (${Function_Name} == "" )
@Composable
fun ${NAME}() {
}
@Preview
@Composable
fun ${NAME}Preview() {
${NAME}()
}
#end
#if (${Function_Name} != "" )
@Composable
fun ${Function_Name}() {
}
@Preview
@Composable
fun ${Function_Name}Preview() {
${Function_Name}()
}
#end
-
3、使用,右击选择New->kotlin compose
基本框架搭建
效果图
- 1、新建项目,修改MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeProjectTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
MainFrame()
}
}
}
}
}
- 2、MainFrame
@Composable
fun MainFrame() {
val navigationItems = listOf(
NavigationItem("首页", Icons.Default.Home),
NavigationItem("项目", Icons.Default.Article),
NavigationItem("分类", Icons.Default.Category),
NavigationItem("我的", Icons.Default.Person)
)
var currentNavigationIndex by remember {
mutableStateOf(0)
}
Scaffold(
bottomBar = {
BottomNavigation(backgroundColor = MaterialTheme.colors.surface) {
navigationItems.forEachIndexed { index, navigationItem ->
BottomNavigationItem(
selected = currentNavigationIndex == index,
onClick = { currentNavigationIndex = index },
icon = {
Icon(imageVector = navigationItem.icon, contentDescription = null)
},
label = {
Text(text = navigationItem.title)
},
selectedContentColor = Color_149EE7,
unselectedContentColor = Color_999999
)
}
}
},
) {
when (currentNavigationIndex) {
0 -> HomeFragment()
1 -> ProjectFragment()
2 -> TypeFragment()
else -> MineFragment()
}
}
}
代码其实很简单,主要通过Scaffold来搭建一个项目结构,用remember+ mutableStateOf来记住状态。内容区域通过选中的index来展示不同的Fragment
- 3、这里运用到Google的一个图标库
- 图标地址:https://fonts.google.com/icons
- 集成依赖
implementation "androidx.compose.material:material-icons-extended:$compose_version"
总结
到这里呢,基本框架已经搭完了,其实还是比较简单的。有不动的呢,可以多看看Google官方文档:https://developer.android.google.cn/jetpack/compose