效果
实现方法
弹窗实现
使用compose material的ModalBottomSheetLayout组件(如果没有请添加依赖
“androidx.compose.material:material:$compose_version”),它可以显示一组选项,同时阻止与屏幕其余部分的交互,在点击屏幕其他地方时会自动缩回。
拍照和文件选择实现
“友善”的compose其实已经为我们准备好了,利用rememberLauncherForActivityResult,我们可以轻松向Activity#startActivityForResult注册一个请求,
所以我们就可以轻松在组件内进行拍照和选择文件。
实现代码
弹窗实现
val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()
ModalBottomSheetLayout(sheetState = sheetState, sheetContent = {
//这里显示底部弹窗内容
}, content = {
//处理后退事件,显示和隐藏必须用协程执行
BackHandler(sheetState.isVisible) {
coroutineScope.launch {
sheetState.hide()
}
}
//显示页面内容
})
sheetState.show()//显示弹窗
拍照和文件选择实现(别忘了请求权限)
val context = LocalContext.current
var mCameraUri: Uri? = null
//通知图片更新
val imagePath = remember {//Record the picture path
mutableStateOf("")
}
//onResult会根据我们的contract返回不同的结果
val openCameraLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.TakePicture(),
onResult = {//这里返回的是boolean
if (it) {
imagePath.value = FileUri.getPathByUri(mCameraUri) ?: ""
}
})
//创建拍照保存的地址
mCameraUri = context.contentResolver.insert(
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED)
MediaStore.Images.Media.EXTERNAL_CONTENT_URI else
MediaStore.Images.Media.INTERNAL_CONTENT_URI, ContentValues()
)
//不同的注册类型需要传进launch里的参数类型也不同
//这里需要传保存图片的uri地址
openCameraLauncher.launch(mCameraUri)//启动
val openSelectPhotoLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent(),
onResult = {//这里返回的是uri?
it?.let {
imagePath.value = FileUri.getPathByUri(it) ?: ""
}
})
//这里需要传选择文件的类型
openSelectPhotoLauncher.launch("image/*")//启动
更多组件可以到ModalBottomSheetLayout | 你好 Compose (jetpackcompose.cn)
和
Material 组件和布局 | Jetpack Compose | Android Developers (google.cn)学习