学习参考资料
集成
implementation "androidx.compose.ui:ui:1.1.0-beta01"
implementation "androidx.compose.material:material:1.1.0-beta01"
implementation "androidx.compose.ui:ui-tooling-preview:1.1.0-beta01"
Activity 中使用
implementation 'androidx.activity:activity-compose:1.3.1'
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import com.wxfggzs.app.ui.theme.ComposeappTheme
class MyComposeActivity() : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeappTheme() {
androidx.compose.material.Surface() {
Column {
Button(onClick = {
Toast.makeText(this@MyComposeActivity, "Hello 1", Toast.LENGTH_LONG)
.show()
}) {
Text(text = "Hello 1")
}
Button(onClick = {
Toast.makeText(this@MyComposeActivity, "Hello 2", Toast.LENGTH_LONG)
.show()
}) {
Text(text = "Hello 2")
}
}
}
}
}
}
}
Fragment 中使用
implementation 'androidx.fragment:fragment-ktx:1.3.5'
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
class MyFragment() : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return ComposeView(requireContext()).apply {
setContent {
Column {
Button(onClick = {
Toast.makeText(context, "Hello 1", Toast.LENGTH_LONG).show()
}) {
Text(text = "Hello 1")
}
Button(onClick = {
Toast.makeText(context, "Hello 2", Toast.LENGTH_LONG).show()
}) {
Text(text = "Hello 2")
}
}
}
}
}
}
组件
与 Compose 捆绑的可组合组件分为三类,称为 Layout、Foundation 和 Material Design 组件。
Layout(布局 )
Column
属性解释
Column {
// 循环10次
for (i in 0..5) {
Text(text = "Hello ${i}")
}
}
- 纵向排列
Row
verticalAlignment 和 horizontalArrangement 属性
属性 | 说明 |
---|---|
horizontalArrangement = Arrangement.Start | 水平左侧 |
horizontalArrangement = Arrangement.Center | 水平居中 |
horizontalArrangement = Arrangement.End | 水平右侧 |
verticalAlignment = Arrangement.Top | 垂直顶部 |
verticalAlignment = Arrangement.CenterVertically | 垂直居中 |
verticalAlignment = Arrangement.Bottom | 垂直底部 |
Row(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(Color.Gray),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.End
) {
Text(text = "1")
Text(text = "2")
Text(text = "3")
Text(text = "4")
Text(text = "5")
}
Row {
// 循环10次
for (i in 0..5) {
Text(text = "Hello ${i}")
}
}
- 横向排列
Box
内容对其方式
Box(
modifier = Modifier
.size(height = 300.dp, width = 300.dp)
.background(Color.LightGray)
) {
Text("TopStart", Modifier.align(Alignment.TopStart))
Text("TopCenter", Modifier.align(Alignment.TopCenter))
Text("TopEnd", Modifier.align(Alignment.TopEnd))
Text("CenterStart", Modifier.align(Alignment.CenterStart))
Text("Center", Modifier.align(Alignment.Center))
Text(text = "CenterEnd", Modifier.align(Alignment.CenterEnd))
Text("BottomStart", Modifier.align(Alignment.BottomStart))
Text("BottomCenter", Modifier.align(Alignment.BottomCenter))
Text("BottomEnd", Modifier.align(Alignment.BottomEnd))
}
指定内容位置
Box(
modifier = Modifier
.size(height = 300.dp, width = 300.dp)
.background(Color.LightGray),
contentAlignment = Alignment.BottomEnd
) {
Text(text = "Hello World")
}
CircleShape(圆)
Box(
Modifier
.size(200.dp)
.clip(CircleShape)
.background(Color.Cyan)
)
RoundedCornerShape(圆角)
Box(
Modifier
.size(200.dp)
.clip(RoundedCornerShape(30.dp))
.background(Color.Blue)
)
CutCornerShape
作为圆角的替代方案,组合项也可以使用切角进行渲染。在这种情况下,CutCornerShape 将传递角的切割长度。可以再次为每个角指定不同的值,或者使用单个长度参数等量切割所有角:
Box(
Modifier
.size(200.dp)
.clip(CutCornerShape(30.dp))
.background(Color.Blue))
BoxWithConstraints
ConstraintLayout
基础组件 (Foundation)
BaseTextField
Canvas
绘制矩形
androidx.compose.foundation.Canvas(modifier = Modifier.fillMaxSize()) {
// 绘制矩形
drawRect(
Color.Blue,
topLeft = Offset(0f, 0f),
size = Size(100f, 100f)
)
}
绘制圆形
androidx.compose.foundation.Canvas(modifier = Modifier.fillMaxSize()) {
// 绘制圆
drawCircle(Color.Red, center = Offset(200f, 200f), radius = 40f)
}
绘制直线
绘制一个缩放以适合给定矩形内的弧
androidx.compose.foundation.Canvas(modifier = Modifier.fillMaxSize()) {
drawArc(
Color.Black,
0f,
60f,
useCenter = true,
size = Size(300f, 300f),
topLeft = Offset(60f, 60f)
)
}
Image
Image(
painter = painterResource(R.drawable.image_text_style_1_0),
contentDescription = null,
modifier = Modifier
.size(200.dp, 200.dp)
.padding(10.dp)
)
LazyColumn
LazyRow
Shape
Text
Material Design
AlertDialog
setContent {
val openDialog = remember { mutableStateOf(false) }
androidx.compose.material.Surface {
Button(onClick = { openDialog.value = true }
) {
Text(text = "打开弹窗")
}
if (openDialog.value) {
AlertDialog(
onDismissRequest = {
openDialog.value = false
},
title = {
Text(text = "提示!")
},
text = {
Text(text = "获得金币奖励100")
},
confirmButton = {
Button(
onClick = {
openDialog.value = false
}) {
Text("确认")
}
},
dismissButton = {
Button(
onClick = {
openDialog.value = false
}) {
Text("取消")
}
}
)
}
}
}
|
Button
colors
@Composable
fun ButtonExample() {
var context = LocalContext.current;
Row {
Button(onClick = {
Toast.makeText(context, "click button", Toast.LENGTH_LONG).show()
}) {
Text(text = "Hello Button")
}
}
}
Card
CircularProgressIndicator
DropdownMenu
Checkbox
FloatingActionButton
LinearProgressIndicator
ModalDrawer
RadioButton
Scaffold
Slider
Snackbar
Switch
@Preview
@Composable
fun MySwitch() {
val checked = remember { mutableStateOf(true) }
Box {
Switch(
checked = checked.value,
onCheckedChange = { checked.value = it }
)
if (checked.value) {
Text(
text = "开",
modifier = Modifier.align(alignment = Alignment.BottomCenter)
)
} else {
Text(
text = "关",
modifier = Modifier.align(alignment = Alignment.BottomCenter)
)
}
}
}
关 | 开 |
---|---|
![]() | ![]() |
|
TextField
TopAppBar
BottomNavigation
Icon
Icon(
Icons.Rounded.Home,
contentDescription = "",
modifier = Modifier
.size(200.dp, 200.dp)
.padding(10.dp)
)
Divider
Column {
Text("第一行")
Divider(startIndent = 8.dp, thickness = 1.dp, color = Color.Black)
Text("第二行")
Divider(startIndent = 8.dp, thickness = 1.dp, color = Color.Black)
Text("第三行")
}
AndroidView
- 广告View
AndroidView(factory = { context ->
RelativeLayout(context).apply {
addView(
View.inflate(context, R.layout.view_test, null),
RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
)
}
})
Jetpack 组合状态和重组
@Composable
fun MemberExample() {
var r = remember {
mutableStateOf(1)
}
Row() {
Button(onClick = { r.value += 1 }) {
Text(text = "${r.value}")
}
}
}
物理返回按键
@Composable
fun BackHandlerExample(context: Context) {
BackHandler(enabled = true, onBack = {
Toast.makeText(context, "按下物理返回按键", Toast.LENGTH_LONG).show()
})
}
退出应用提示
@Composable
fun ExitAppHint() {
val exitShow = remember { mutableStateOf(false) }
BackHandler(enabled = true, onBack = {
exitShow.value = true
})
if (exitShow.value) {
AlertDialog(
onDismissRequest = {
exitShow.value = false
},
title = {
Text(text = "提示!")
},
text = {
Text(text = "退出应用?")
},
confirmButton = {
Button(
onClick = {
exitShow.value = false
System.exit(0)
}) {
Text("确认")
}
},
dismissButton = {
Button(
onClick = {
exitShow.value = false
}) {
Text("取消")
}
}
)
}
}
如何检测暗模式
val dark = isSystemInDarkTheme()
Lottie
@Composable
fun Loader() {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
val progress by animateLottieCompositionAsState(
composition,
iterations = LottieConstants.IterateForever
)
LottieAnimation(composition, { progress })
}
获取Context
https://foso.github.io/Jetpack-Compose-Playground/cookbook/get_android_context/
// 获取Context
val ccontex = LocalContext.current;
组件属性
Modifier
size(size: DpSize)
设置宽高为size
定义
@Stable
fun Modifier.size(size: DpSize) = size(size.width, size.height)
size(width: Dp, height: Dp)
设置宽高 width. 和 height
定义
@Stable
fun Modifier.size(width: Dp, height: Dp) = this.then(
SizeModifier(
minWidth = width,
maxWidth = width,
minHeight = height,
maxHeight = height,
enforceIncoming = true,
inspectorInfo = debugInspectorInfo {
name = "size"
properties["width"] = width
properties["height"] = height
}
)
)
clip(shape: Shape)
- RoundedCornerShape
- CircleShape