一些实用的知识总是用起来的时候提笔忘字,所以专门开帖子记录
993、compose绘制背景
compose绘制背景使用drawBehind操作符来实现
例如如果我们想设置聊天背景,那么因为compose是无法直接设置图片背景的,所以.9.png就无法使用,这个使用可以使用drawBehind来了实现背景绘制(只能绘制纯色,带图案的无法拉伸,这一点还是不能完全替代.9.png)。
drawBehind操作符和background操作符冲突,会互相覆盖
代码
Box(Modifier.background(Color.Red)) {
Box(Modifier
.size(80.dp)
.drawBehind {
drawImage(
bitmap.asImageBitmap(),
srcSize = IntSize(bitmap.width, bitmap.height),
dstSize = IntSize((density * 50).toInt(), (density * 50).toInt()),
srcOffset = IntOffset.Zero,
dstOffset = IntOffset.Zero
)
}) {
}
Text(text = "将图片绘制到成一个宽高50dp的情况")
}
Box(Modifier.background(Color.Red)) {
Box(Modifier
.size(80.dp)
.drawBehind {
val density = density.toInt()
this.drawImage(
bitmap.asImageBitmap(),
srcOffset = IntOffset(15 * density, 15 * density),
srcSize = IntSize(bitmap.width, bitmap.height),
dstOffset = IntOffset(40 * density, 40 * density),
dstSize = IntSize(density * 35, density * 35)
)
// dstSize = IntSize(density * 50, density * 50)
}) {
}
Text(text = "将图片绘制到成一个宽高50dp的情况")
}
995、 Compose更改输入框键盘回车键行为的方式 (20220404)
代码
关键就是下面的三个属性:
其中keyboardOption
用来设置输入的内容类型和返回键展示的样式
keyboardActions
用来展示回车键被点击相应的行为后的回调方法
singleLine=true
尤其要设置单行为true,否则回车键的行为图标不会发生改变
singleLine = true, keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = actionData.imeAction
), keyboardActions = KeyboardActions(
onDone = {
showToast("onDone")
},
onGo = {
showToast("onGo")
},
onNext = {
showToast("onNext")
},
onPrevious = {
showToast("onPrevious")
},
onSearch = {
showToast("onSearch")
},
onSend = {
showToast("onSend")
}
)
实现效果
995、Compose实现键盘弹出和关闭的方法
代码
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun KeyboardShowAndHide() {
var text by remember {
mutableStateOf("")
}
val requester = remember {//用于请求焦点的对象
FocusRequester()
}
val keyboard = LocalSoftwareKeyboardController.current//用于操作键盘的对象
LaunchedEffect(key1 = Unit, block = {
requester.requestFocus()//首次进入和重组页面请求焦点
keyboard?.show()//首次进入页面弹出键盘,注意必须先获取焦点才能弹出键盘成功
})
Column(
Modifier
.padding(top = 150.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = text, onValueChange = {
text = it
}, modifier = Modifier.focusRequester(requester)//focusRequester方法表明让OutLineTextField可以获取焦点
)
Button(onClick = {
requester.requestFocus()//替OutLineTextField请求焦点,一定要获取焦点才能操作键盘
keyboard?.hide()//关闭键盘
}, modifier = Modifier.fillMaxWidth()) {
Text(text = "关闭键盘")
}
}
}
效果
996、Compose中使用mutableStateListOf实现列表数据观察
我们实现这样一个需求,在ViewModel中声明一个mutableStateListOf的对象datas。然后我们使用这个列表渲染数据,当我们点击列表中item的时候就向datas中添加一条数据,然后列表的数据可以实时刷新预览。
?为什么我们要使用mutableStateListOf而不是mutableListOf呢,因为如果使用mutableListOf那么当我们向列表中添加数据的时候,我们渲染的列表是无法更新数据预览的。所以我们必须使用mutableStateListOf。
实现代码如下
@Composable
fun Test() {
val model: TestModel = viewModel()
CustomScaffold(title = "测试页面") {
LazyColumn(content = {
itemsIndexed(model.datas) { index: Int, data: Int ->
Box(
Modifier
.padding(5.dp)
.fillMaxWidth()
.height(50.dp)
.border(width = 1.dp, color = Color.Green)
.clickable {
model.datas.add(index + 1)
},
contentAlignment = Alignment.Center
) {
if (index == model.datas.size - 1) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "",
tint = Color.Red
)
} else {
Text(text = data.toString())
}
}
}
})
}
}
class TestModel : ViewModel() {
val datas = mutableStateListOf(0)
// val datas = mutableListOf(0,1,2,3)
}
git:https://github.com/ananananzhuo-blog/ComposeApiSample/blob/main/app/src/main/java/com/ananananzhuo/composeapi/ui/function/MutableStateListOfView.kt
实现效果
997、Compose返回键监听方法
方法1
@Composable
fun Back1(controller: NavHostController) {
Column(
Modifier
.fillMaxSize()
.background(Color.Red)
.clickable {
controller.popBackStack()
}) {
Text(text = "点击返回上一个页面")
Text(text = "使用BackHandler实现返回键监听")
}
BackHandler(enabled = true) {
Log.e("tag","返回键被点击")
}
}
方法2
在@Composable方法中加入如下监听设置,方法1的实现方式就是使用如下方式实现的
@Composable
fun Back2(controller: NavHostController) {
Column(
Modifier
.fillMaxSize()
.background(Color.Green)
.clickable {
controller.popBackStack()
}) {
Text(text = "点击返回上一个页面")
Text(text = "使用OnBackPressedDispatcher监听返回键被点击")
}
val callback = remember {
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
log("回退键被点击")
showToast("监听到返回键被点击监听")
}
}
}
val dispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
DisposableEffect(key1 = Unit, effect = {
dispatcher?.addCallback(callback)
onDispose {
callback.remove()
}
})
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQozz9aR-1648286447554)(https://github.com/ananananzhuo-blog/ComposeApiSample/blob/main/app/src/main/java/com/ananananzhuo/composeapi/ui/function/BackKey.kt)]
998、防快速点击
说明
防快速点击主要使用 Modifier 操作符来实现,代码如下
代码
@Composable
fun Modifier.avoidRepeatclickable(millis: Long = 500, onClick: () -> Unit): Modifier {
var timeStamp by remember {
mutableStateOf(0L)
}
return clickable {
if (System.currentTimeMillis() - timeStamp > millis) {
onClick()
timeStamp = System.currentTimeMillis()
}
}
}
git:https://github.com/ananananzhuo-blog/ComposeApiSample/blob/main/app/src/main/java/com/ananananzhuo/composeapi/ui/function/AvoidFastClick.kt
效果
gif 中有两个按钮,
-
第一个使用正常的 clickable,每次点击悲剧都会变色;
-
第二个按钮使用了我们的防快速点击操作符,500ms 内多次点击之后出发一次背景变色;
999、Compose 中跳转 Activity,并获取返回结果
说明
这里需要使用 ActivityResult Api,compose 专门进行了扩展
需要使用的扩展库如下:
androidx.activity:activity-compose:1.3.0
代码
val launcher = rememberLauncherForActivityResult(contract =object : ActivityResultContract<String, String>() {
override fun parseResult(resultCode: Int, intent: Intent?): String {
return intent?.getStringExtra("data")?:""
}
/**
* @param compose向Compose中传的数据 ActivityResultContract<String, String>的第一个泛型
*/
override fun createIntent(context: Context, input: String?): Intent {
return Intent(context,GenerateActivityResultActivity::class.java).apply {
putExtra("data",input)
}
}
} , onResult = {result-> //result 是ActivityResultContract<String, String>第二个泛型
activityResult = result
})
git 地址:https://github.com/ananananzhuo-blog/ComposeApiSample/blob/main/app/src/main/java/com/ananananzhuo/composeapi/ui/function/LaunchToActivityExpectResult.kt