Jetpack Compose学习 -------- AnimationVisibility

AnimationVisibility 动画 可见 基础用法

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

@ExperimentalAnimationApi
@Composable
fun ComposableSample() {
var state by remember {
mutableStateOf(true)
}
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
AnimatedVisibility(visible = state) {
Text(
text = "这是一个普通的正文",
fontWeight = FontWeight.W900,
style = MaterialTheme.typography.h5
)
}
Spacer(modifier = Modifier.height(50.dp))
Button(onClick = { state = !state }) {
Text(
text = if (state) {
"隐藏"
} else {
"显示"
}
)
}
}
}

进场动画

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

@ExperimentalAnimationApi
@Composable
fun ComposableSample() {
var state by remember { mutableStateOf(true) }
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
AnimatedVisibility(
visible = state,
enter = slideInVertically(
//初始位置 Y轴
initialOffsetY = { -1000 },
animationSpec = tween(
//动画持续时间
durationMillis = 1200
)
)
) {
Text(
text = "这是一个普通的正文",
fontWeight = FontWeight.W900,
style = MaterialTheme.typography.h5
)
}
Spacer(modifier = Modifier.height(50.dp))
Button(onClick = { state = !state }) {
Text(
text = if (state) {
"隐藏"
} else {
"显示"
}
)
}
}
}

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

@ExperimentalAnimationApi
@Composable
fun ComposableSample() {
var state by remember { mutableStateOf(true) }
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
AnimatedVisibility(
visible = state,
//垂直滑入
enter = slideInVertically(
//初始位置 Y轴
initialOffsetY = { -1000 },
animationSpec = tween(
//动画持续时间
durationMillis = 1200
)
//淡入
) + fadeIn(
animationSpec = tween(
//动画持续时间
durationMillis = 1200
)
)
) {
Text(
text = "这是一个普通的正文",
fontWeight = FontWeight.W900,
style = MaterialTheme.typography.h5
)
}
Spacer(modifier = Modifier.height(50.dp))
Button(onClick = { state = !state }) {
Text(
text = if (state) {
"隐藏"
} else {
"显示"
}
)
}
}
}

Jetpack Compose学习 -------- Swipeable 滑动

Swipeable 滑动 基本使用

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


@Composable
fun ComposableSample() {
var blockSize = 48.dp
var blockSizePx = with(LocalDensity.current) { blockSize.toPx() }
var swipeableState = rememberSwipeableState(initialValue = Status.CLOSE)
var anchors = mapOf(
0f to Status.CLOSE,
blockSizePx to Status.OPEN
)
Box(
modifier = Modifier
.size(
height = blockSize,
width = blockSize * 2
)
.background(Color.LightGray)
) {
Box(
modifier = Modifier
//滑动
.swipeable(
state = swipeableState,
//锚点,可以通过锚点设置在不同状态时所应该对应的偏移量信息
anchors = anchors,
//常用作定制不同锚点间吸附效果的临界阈值
//常用有 FixedThreshold(Dp) 和 FractionalThreshold(Float)等
thresholds = { from, to ->
if (from == Status.CLOSE) {
FractionalThreshold(0.3f)
} else {
FractionalThreshold(0.5f)
}
},
//手势方向,被修饰组件的手势方向只能是水平或垂直
orientation = Orientation.Horizontal,
)
//移动
.offset {
//整体移动
IntOffset(swipeableState.offset.value.toInt(), 0)
}
.size(blockSize)
.background(Color.DarkGray)
)
}
}

enum class Status {
CLOSE, OPEN
}


Jetpack Compose学习 -------- ModalBottomSheetLayout 底部弹出布局

ModalBottomSheetLayout 底部弹出布局 基本使用

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

@ExperimentalMaterialApi
@Composable
fun ComposableSample() {
val state = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetContent = {
Column {
ListItem(
text = {
Text(text = "选择分享到哪里吧~")
}
)
ListItem(
text = {
Text(text = "github")
},
icon = {
Surface(
shape = CircleShape,
color = Color(0xFF181717)
) {
Icon(
painterResource(id = R.drawable.ic_github),
null,
Modifier.padding(4.dp),
Color.White
)
}
}, modifier = Modifier.clickable { }
)
ListItem(
text = {
Text(text = "wechat")
},
icon = {
Surface(
shape = CircleShape,
color = Color(0xFF181717)
) {
Icon(
painterResource(id = R.drawable.ic_wechat),
null,
Modifier.padding(4.dp),
Color.White
)
}
}, modifier = Modifier.clickable { }
)
ListItem(
text = {
Text(text = "twitter")
},
icon = {
Surface(
shape = CircleShape,
color = Color(0xFF181717)
) {
Icon(
painterResource(id = R.drawable.ic_twitter),
null,
Modifier.padding(4.dp),
Color.White
)
}
}, modifier = Modifier.clickable { }
)
}
},
sheetState = state
) {
Column(
Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = {
scope.launch {
state.show()
}
}) {
Text(text = "分享")
}
}
}
//返回键 处理 ModalBottomSheet 收回
BackHandler(
enabled = (state.currentValue == ModalBottomSheetValue.HalfExpanded ||
state.currentValue == ModalBottomSheetValue.Expanded),
onBack = {
scope.launch {
state.hide()
}
})
}

收回 ModalBottomSheet

一般情况下,ModalBottomSheet 无法自动处理按下返回键就收起,所以我们可以用 BackHandler 来处理
在 ModalBottomSheet 后添加代码:

1
2
3
4
5
6
7
8
9
10
11

BackHandler(
enabled = (state.currentValue == ModalBottomSheetValue.HalfExpanded
|| state.currentValue == ModalBottomSheetValue.Expanded),
onBack = {
scope.launch{
state.hide()
}
}
)

设置动画时间

ModalSheetLayout 默认用 state.show() 或者 state.hidden() 来弹出和收回
我们可以通过这样的方式来自定义动画时间:

1
2
3

state.animateTo(ModalBottomSheetValue.Hidden, tween(1000))

Jetpack Compose学习 -------- BottomNavigation 底部导航栏

BottomNavigation 底部导航栏 基本使用

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

@Composable
fun ComposableSample() {
var selectedItem by remember {
mutableStateOf(0)
}
val list_name = listOf("主页", "喜爱", "设置")
val list_icon = listOf(Icons.Filled.Home, Icons.Filled.Favorite, Icons.Filled.Settings)
Scaffold(
topBar = {
//顶部导航栏
TopAppBar(
title = {
Text(text = list_name.get(selectedItem))
},
navigationIcon = {
IconButton(onClick = {}) {
Icon(Icons.Filled.ArrowBack, null)
}
}
)
},
bottomBar = {
BottomNavigation {
list_name.forEachIndexed { index, item ->
BottomNavigationItem(
selected = selectedItem == index,
onClick = { selectedItem = index },
icon = {
Icon(
imageVector = list_icon[index],
contentDescription = null,
)
}, label = {
Text(text = item)
})
}
}
}
) {
Text(
text = list_name[selectedItem],
Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center)
)
}
}


Jetpack Compose学习 -------- Surface

用 Surface 实现 Card 的效果

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

@Composable
fun ComposableSample() {
Surface(
//设置形状
shape = RoundedCornerShape(10.dp),
// 设置阴影
elevation = 10.dp,
modifier = Modifier
.fillMaxWidth()
// 外边距
.padding(15.dp)
.clickable { }
) {
Column(
// 内边距
Modifier.padding(15.dp)
) {
Text(
buildAnnotatedString {
append("welcome to ")
withStyle(
style = SpanStyle(
color = Color(0xFF4552B8),
fontWeight = FontWeight.W900,
)
) {
append("Jetpack Compose Playground")
}
})
Text(
buildAnnotatedString {
append("Now you are in the ")
withStyle(
style = SpanStyle(
fontWeight = FontWeight.W900,
)
) {
append("Card")
}
append(" section")
})
}
}
}