Jetpack Compose学习 -------- 图片 Image , Icon

Image 图片 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

@Composable
fun ImageResourceDemo() {
val image = painterResource(id = R.mipmap.icon_header)
Column {
Image(
painter = image,
contentDescription = "图片描述"
)
Image(
painter = image,
contentDescription = "图片描述",
//设置图片大小
modifier = Modifier.size(100.dp)
)
Surface(
//设置形状
shape = CircleShape
) {
Image(
painter = image,
contentDescription = "图片描述",
//设置图片大小
modifier = Modifier.size(100.dp),
//保持宽高比缩放
contentScale = ContentScale.Crop
)
}

Surface(
//设置形状
shape = CircleShape,
//边框
border = BorderStroke(2.dp, Color.Gray),
) {
Image(
painter = image,
contentDescription = "图片描述",
//设置图片大小
modifier = Modifier.size(100.dp),
//保持宽高比缩放
contentScale = ContentScale.Crop
)
}
}
}

图片加载

1
2
3
4
//图片加载    
implementation("com.github.bumptech.glide:glide:4.12.0")
annotationProcessor("com.github.bumptech.glide:compiler:4.12.0")
implementation("com.google.accompanist:accompanist-glide:0.10.0")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

import com.google.accompanist.glide.rememberGlidePainter

@Composable
fun ComposableSample() {
Column(
Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
val str_img_url by remember {
mutableStateOf(
"https://tenfei04.cfp.cn/creative/vcg/veer/800water/veer-170860698.jpg"
)
}
Image(
painter = rememberGlidePainter(
request = str_img_url,
//占位图片
previewPlaceholder = R.mipmap.ic_launcher,
),
null,
Modifier.size(100.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Image(painter = rememberGlidePainter(
request = str_img_url,
requestBuilder = {
//圆形
transform(CircleCrop())
}
), contentDescription = null,
Modifier.size(100.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Image(painter = rememberGlidePainter(
request = str_img_url,
requestBuilder = {
//圆角
transform(RoundedCorners(20))
}
), contentDescription = null,
Modifier.size(100.dp)
)
}
}

自定义控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@Composable
fun ComposableSample() {
val painter =
rememberGlidePainter(
request = "https://tva1.sinaimg.cn/large/a15b4afegy1fmvjlgdxxgj21hc0u04qp.jpg"
)
Box(Modifier.fillMaxSize()) {
Image(
painter = painter,
contentDescription = null,
//居中
Modifier.align(Alignment.Center)
)
//加载状态
when (painter.loadState) {
//加载中
is ImageLoadState.Loading -> {
//圆形进度条
CircularProgressIndicator(
//居中
Modifier.align(Alignment.Center)
)
Snackbar {
Text(text = "图片加载中")
}
}
//加载失败
is ImageLoadState.Error -> {
Snackbar {
Text(text = "图片加载失败")
}
}
//加载成功
is ImageLoadState.Success -> {
Snackbar {
Text(text = "图片加载成功")
}
}

}
}
}

Icon 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Composable
fun ComposableSample() {
Row {
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.Gray)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.Red)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.DarkGray)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.Magenta)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.Cyan)
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null, tint = Color.Blue)
}
}

Jetpack Compose学习 -------- DropdownMenu 下拉菜单

DropdownMenu 下拉菜单 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

@Composable
fun DropdownSample() {
val isExpanded = remember {
mutableStateOf(false)
}
val list = listOf("A", "B", "C", "D", "E", "F", "G")
val disabledValue = "B"
var selectedIndex = remember {
mutableStateOf(0)
}
Box(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
) {
Text(
text = list[selectedIndex.value],
modifier = Modifier
.fillMaxWidth()
.height(30.dp)
.padding(10.dp)
.clickable {
isExpanded.value = true
}
.background(
Color.Black
),
color = Color.White
)
DropdownMenu(
expanded = isExpanded.value,
onDismissRequest = { isExpanded.value = false },
modifier = Modifier
.fillMaxWidth()
.background(Color.Red)
) {
list.forEachIndexed { index, s ->
DropdownMenuItem(onClick = {
selectedIndex.value = index
isExpanded.value = false
}
) {
val disaledText = if (disabledValue == s) {
" (Disabled)"
} else {
""
}
Text(text = "${s}${disaledText}")
}
}
}
}
}

Jetpack Compose学习 -------- Crossfade

Crossfade 动画 淡入淡出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

enum class MyColors(val color: Color) {
Red(Color.Red),
Green(Color.Green),
Blue(Color.Blue),
}

//淡入淡出 动画
@Composable
fun CrossfadeDemo() {
var currentColor = remember {
mutableStateOf(MyColors.Red)
}
Column {
Row {
MyColors.values().forEach { myColors ->
Button(
onClick = { currentColor.value = myColors },
Modifier.weight(1f, true)
.height(48.dp)
.background(myColors.color),
colors = ButtonDefaults.buttonColors(
backgroundColor = myColors.color
)
) {
Text(myColors.name, color = Color.White)
}
}
}
//淡入淡出 切换动画
Crossfade(
targetState = currentColor,
animationSpec = tween(3000)
) { selectedColor ->
Box(
modifier = Modifier
.fillMaxSize()
.background(color = selectedColor.value.color)
)
}
}
}

Jetpack Compose学习 -------- 布局 Column Row Box Spacer BoxWithConstraints ConstraintLayout

Column 垂直布局(将多个项垂直地放置在屏幕上)

1
2
3
4
5
6
7
8
@Composable
fun ColumnLayoutDemo() {
//垂直布局
Column {
Text(text = "Alfred Sisley")
Text(text = "3 minutes ago")
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Composable
fun ComposableSample() {
//文字居中
Column(
Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("你好呀")
Text("我正在使用 Android Studio")
Text("现在是晚上")
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@Composable
fun ComposableSample() {
//特定文字居中
Column(
Modifier.fillMaxWidth(),
) {
Text(
text = "夜色",
//特定文字居中
modifier = Modifier.align(Alignment.CenterHorizontally),
style = MaterialTheme.typography.h6,
fontWeight = FontWeight.W900
)
Text("今晚的夜色很不错,我和朋友走在河边的小路上,看到了很多美丽的风景")
}
}

Row 水平布局 (将多个项水平地放置在屏幕上)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  @Composable
fun RowLayoutDemo() {
//水平布局
Row(verticalAlignment = Alignment.CenterVertically) {
//图片
Image(
painter = painterResource(id = R.mipmap.icon_header),
contentDescription = null
)
//垂直布局
Column {
Text(text = "Alfred Sisley")
Text(text = "3 minutes ago")
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Preview
@Composable
fun AlignInRowDemo() {
Row(
modifier = Modifier
.size(150.dp)
.background(Color.Gray),
//水平排列
horizontalArrangement = Arrangement.End,
//垂直排列
verticalAlignment = Alignment.CenterVertically,
) {
Box(Modifier.size(50.dp).background(Color.Yellow))
Box(Modifier.size(50.dp).background(Color.Blue))
}
}

1
2
3
4
5
6
7
8
9
10

@Composable
fun ComposableSample() {
Row {
Box(Modifier.size(40.dp).background(Color.Magenta))
Box(Modifier.size(40.dp).background(Color.Yellow))
Box(Modifier.size(40.dp).background(Color.Green))
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

@Composable
fun ComposableSample() {
Row {
Box(
Modifier
.size(40.dp)
//权重
.weight(1f)
.background(Color.Magenta)
)
Box(
Modifier
.size(40.dp)
.background(Color.Yellow))
Box(
Modifier
.size(40.dp)
//权重
.weight(1f)
.background(Color.Green))
}
}

Box 水平布局 (将一个元素放在另一个元素上)

1
2
3
4
5
6
7
@Composable
fun BoxLayoutDemo() {
Box() {
Text(text = "测试", color = Color.Blue, fontSize = 15.sp)
Text(text = "测试", color = Color.Yellow, fontSize = 30.sp)
}
}

Spacer 空白布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

@Composable
fun ComposableSample() {
Row {
Box(
Modifier
.size(100.dp)
.background(Color.Magenta)
)
//空白布局
Spacer(modifier = Modifier.width(20.dp))
Box(
Modifier
.size(100.dp)
.background(Color.Yellow)
)
Spacer(modifier = Modifier.weight(1f))
Box(
Modifier
.size(100.dp)
.background(Color.Green)
)
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@Composable
fun ArtistCardDemo() {
val padding = 16.dp
Column(
Modifier
.clickable(onClick = {
Log.d("Clickable", " clicked.")
})
.padding(padding)
.fillMaxWidth()
) {
RowLayoutDemo()
Spacer(Modifier.size(padding))
Card(elevation = 4.dp) {
Image(
painter = painterResource(id = R.mipmap.icon_header),
contentDescription = null
)
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

//内边距
@Composable
fun PaddedComposableDemo() {
Text(
text="Hello World",
modifier =
//背景
Modifier.background(Color.Green)
//内边距
.padding(20.dp))

}

1
2
3
4
5
6
7
8
9
10

//设置尺寸
@Composable
fun SizedComposableDemo() {
Box(
//设置尺寸
modifier = Modifier.size(100.dp, 100.dp)
//背景
.background(Color.Red))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Composable
fun FixedSizeComposableDemo() {
Box(
modifier =
Modifier
//设置尺寸
.size(90.dp, 150.dp)
//背景
.background(Color.Blue)
) {
//设置所需尺寸
Box(
Modifier
.requiredSize(120.dp, 120.dp)
//背景
.background(Color.Red)
)
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Composable
fun FillSizeComposableDemo() {
Box(
Modifier
//背景
.background(Color.Green)
//尺寸
.size(50.dp)
//内边距
.padding(10.dp)
) {
Box(
Modifier
//背景
.background(Color.Blue)
//填充 最大边距
.fillMaxSize()
)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   @Composable
fun MatchParentSizeComposable() {
Box {
Spacer(
modifier = Modifier
// 仅在 Box 作用域内可用
.matchParentSize()
//Spacer 将占用父项允许的所有可用空间,反过来使父项展开并填满所有可用空间
// .fillMaxSize()
.background(Color.Green)
)
Text(text = "Hello World")
}
}
1
2
3
4
5
6
7
8
9
10
11
12
//在文本基线上方添加内边距
@Composable
fun TextWithPaddingFromBaseline() {
Box(modifier = Modifier.background(Color.Green)) {
Text(
text = "Hello World",
modifier = Modifier
//在文本基线上方添加内边距
.paddingFromBaseline(top = 20.dp, bottom = 5.dp)
)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//偏移量
@Composable
fun OffsetComposable() {
Box(
modifier = Modifier
.size(width = 160.dp, height = 80.dp)
.background(Color.Blue)
) {
Text(
text = "Layout offset modifier sample",
//偏移量
Modifier.offset(x = 16.dp, y = 40.dp)
)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//自适应布局
@Composable
fun FlexibleComposable() {
Row(Modifier.width(200.dp)) {
Box(
modifier = Modifier
.weight(1f)
.height(30.dp)
.background(Color.Green)
)
Box(
modifier = Modifier
.weight(3f)
.height(30.dp)
.background(Color.Red)
)
}
}

BoxWithConstraints

1
2
3
4
5
6
7
8
//约束条件
@Composable
fun WithConstraintsComposable() {
//约束条件
BoxWithConstraints {
Text("My minHeight is $minHeight while my maxWidth is $maxWidth")
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

@Composable
fun ComposableSample() {
BoxWithConstraints(
modifier = Modifier.fillMaxWidth(),
//内容的对齐方式
contentAlignment = Alignment.TopStart,
//是否将约束作用于 子 View 上
propagateMinConstraints = true,
) {
val itemW = 50.dp
val spaceW = 2.dp
val count = (maxWidth.value / (itemW.value + spaceW.value)).toInt()
if (count > 0) {
Row() {
for (i in 0 until count) {
Box(
Modifier
.size(itemW, itemW)
.background(Color.Blue)
)
Spacer(Modifier.size(spaceW))
}
}
}
}
}

ConstraintLayout 约束布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Composable
fun ConstraintLayoutDemo() {
ConstraintLayout {
//通过 createRefs() 或 createRefFor() 创建关联的引用
val (text1,text2,text3) = createRefs()
//使用 constrainAs() 修饰符提供的约束条件
Text(text = "Text1", Modifier.constrainAs(text1) {
//指定约束条件
start.linkTo(text2.end)
})
Text(text = "Text2", Modifier.constrainAs(text2) {
top.linkTo(text1.bottom)
})
Text(text = "This is a very long text", Modifier.constrainAs(text3) {
start.linkTo(text2.end)
top.linkTo(text2.bottom)
})
}
}

Jetpack Compose学习 -------- CircularProgressIndicator 圆形进度条

CircularProgressIndicator 圆形进度条 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

@Composable
fun CircularProgressIndicatorSample() {
var progress = remember {
mutableStateOf(0.0f)
}
val animatedProgress = animateFloatAsState(
targetValue = progress.value,
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
).value
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Spacer(modifier = Modifier.height(30.dp))
Text(text = "进度 不确定 的 圆形 进度条")
Spacer(modifier = Modifier.height(30.dp))
CircularProgressIndicator()
Spacer(modifier = Modifier.height(30.dp))
Text(text = "圆形进度条 进度通过 点击按钮 添加")
Spacer(modifier = Modifier.height(30.dp))
CircularProgressIndicator(progress = animatedProgress)
Spacer(modifier = Modifier.height(30.dp))
OutlinedButton(onClick = {
if (progress.value < 1f) {
progress.value += 0.1f
}
}) {
Text(text = "添加进度")
}
Spacer(modifier = Modifier.height(30.dp))
OutlinedButton(onClick = {
if (progress.value > 0f) {
progress.value -= 0.1f
}
}) {
Text(text = "降低进度")
}
}
}