Compose实用知识整理

简介: Compose实用知识整理

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的情况")
}
复制代码


994、 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")
    }
)
复制代码

github.com/ananananzhu…


实现效果

image.png


995、Compose实现键盘弹出和关闭的方法(20220403更新)


代码

@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 = "关闭键盘")
        }
    }
}
复制代码

github.com/ananananzhu…

效果

image.png


Compose中使用mutableStateListOf实现列表数据观察


我们实现这样一个需求,在ViewModel中声明一个mutableStateListOf的对象datas。然后我们使用这个列表渲染数据,当我们点击列表中item的时候就向datas中添加一条数据,然后列表的数据可以实时刷新预览。

?为什么我们要使用mutableStateListOf而不是mutableListOf呢,因为如果使用mutableListOf那么当我们向列表中添加数据的时候,我们渲染的列表是无法更新数据预览的。所以我们必须使用mutableStateListOf。


996、实现代码如下

@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)
}
复制代码

实现效果

image.png


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()
        }
    })
}
复制代码


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:github.com/ananananzhu…

效果

gif 中有两个按钮,

  • 第一个使用正常的 clickable,每次点击悲剧都会变色;
  • 第二个按钮使用了我们的防快速点击操作符,500ms 内多次点击之后出发一次背景变色;

image.png


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 地址:github.com/ananananzhu…



相关文章
|
Android开发 开发者
Android Split APK介绍
【2月更文挑战第5天】
|
编译器 API 容器
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
1114 0
|
10月前
|
存储 IDE 开发工具
错误代码0xc000000e解决办法?
以下是解决错误代码0xc000000e的几种有效方法: 检查硬件连接‌
|
JSON JavaScript API
MCP 实战:用配置与真实代码玩转 GitHub 集成
MCP 实战:用配置与真实代码玩转 GitHub 集成
2562 4
|
Java Maven
[Java ] jdk升级 bug java: -source 8 中不支持 instanceof 中的模式匹配 (请使用 -source 16 或更高版本以启用 instanceof 中的模式匹配)
[Java ] jdk升级 bug java: -source 8 中不支持 instanceof 中的模式匹配 (请使用 -source 16 或更高版本以启用 instanceof 中的模式匹配)
1261 0
|
Java Maven Kotlin
vertx的学习总结7之用kotlin 与vertx搞一个简单的http
本文介绍了如何使用Kotlin和Vert.x创建一个简单的HTTP服务器,包括设置路由、处理GET和POST请求,以及如何使用HTML表单发送数据。
278 2
vertx的学习总结7之用kotlin 与vertx搞一个简单的http
|
存储 安全 API
Android经典实战之存储方案对比:SharedPreferences vs MMKV vs DataStore
本文介绍了 Android 开发中常用的键值对存储方案,包括 SharedPreferences、MMKV 和 DataStore,并对比了它们在性能、并发处理、易用性和稳定性上的特点。通过实际代码示例,帮助开发者根据项目需求选择最适合的存储方案,提升应用性能和用户体验。
1310 1
|
Ubuntu
ubuntu搭建NFS服务 磁盘共享 nfs 搭建
ubuntu搭建NFS服务 磁盘共享 nfs 搭建
747 2
|
缓存 Java 数据库
后端性能优化的实践与经验分享
【5月更文挑战第15天】在互联网环境中,后端性能优化对提供卓越用户体验至关重要。关键领域包括:数据库优化(查询优化、索引优化、表结构优化、数据库维护)、缓存策略(内存缓存、CDN内容分发、HTTP缓存)、服务器配置优化(硬件升级、网络优化、操作系统调整)和代码优化(算法与数据结构、懒加载与异步处理、减少冗余计算、多线程与并发)。通过这些方法,可以提升响应速度,增强用户满意度,促进业务增长。
666 3
|
JavaScript 前端开发
前端 JS 经典:统一 Vite 中图片转换逻辑
前端 JS 经典:统一 Vite 中图片转换逻辑
567 0