持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
Compose尝鲜体验(三)
Compose 常规使用
1、布局
Row Column Box ConstraintLayout
2、Modifier
modifier=Modifier.clip(RoundedCornerShape())
3、脚手架 Scaffold
Scaffold允许您使用基本的 Material Design 布局结构来实现 UI。它为最常见的顶级 Material 组件提供了插槽,例如 TopAppBar、 BottomAppBar、 FloatingActionButton和 Drawer。使用Scaffold,您可以确保这些组件正确定位并协同工作。
kotlin
Scaffold(topBar = {
TopAppBar(
title = {
Text(text = "LayoutsCodelab")
}, actions = {
IconButton(onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Favorite, contentDescription = null)
}
}
)
}
4、自定义布局
使用layout修改器手动控制如何测量和定位元素。通常,自定义layout修饰符的常见结构如下:
kotlin
/**
*measurable 要测量和放置的孩子
*constraints 孩子的宽度和高度的最小值和最大值
*/
fun Modifier.customLayoutModifier(...) = Modifier.layout { measurable, constraints ->
...
})
5、约束布局
kotlin
ConstraintLayout {
//给每个@composeable关联一个引用
val (btn_next1,btn_next2,text) = createRefs()
//使用constrainAs提供约束,该修饰符将引用作为修饰符
nextStepButton(buttonName = "下一步",
modifier =Modifier.constrainAs(btn_next1){
//使用linkTo或其他有用的方法指定约束
top.linkTo(parent.top,margin = 20.dp)
}) {
}
Text(text = "text", Modifier.constrainAs(text) {
top.linkTo(btn_next1.bottom,margin = 20.dp)
/*
*Dimension的行为
*preferredWrapContent 内容自适应,但受约束条件影响,也就是说,当宽小于约束条件下可用的 *宽时,则view的宽就是自身的宽,但大于的时候,则受约束条件影响。
*fillToConstraints 填充约束条件下所剩的可用空间
*wrapContent 内容自适应,不受约束条件影响
*preferredValue 指定固定值大小,受约束条件影响。
*value 指定固定值大小,不受约束条件影响。
*/
width = Dimension.preferredWrapContent
centerAround(btn_next1.end)
})
nextStepButton(buttonName = "取消",
modifier =Modifier.constrainAs(btn_next2){
top.linkTo(parent.top,margin = 20.dp)
start.linkTo(btn_next1.end,margin = 10.dp)
}) {
}
}
6、指定组合项透明程度Alpha
kotlin
//ContentAlpha 标准 alpha 值 ( high, medium, disabled)
ompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
text = text,
modifier = modifier
)
kotlin
/** 下一步按钮
* @param buttonName 按钮名称
* @param modifier 按钮附加修饰符
* @param onclick 按钮单击事件
* **/
@Composable
fun nextStepButton(buttonName: String,modifier: Modifier, onclick: () -> Unit) {
Button(
onClick = onclick,
modifier = modifier
.clip(RoundedCornerShape(15.dp))
.width(200.dp),
colors = ButtonDefaults.buttonColors(backgroundColor = Color(0xFFFD5D59)
,contentColor = Color(0xffffffff)),
) {
Text(text = buttonName)
}
}
7、Compose状态
8、网络加载库Coil\Glide
添加Glide Compose依赖
//glide
implementation "com.google.accompanist:accompanist-glide:0.12.0"
/**Glide使用**/
/**
* @param modifier 外部传入Image的大小
* @param placeholder 占位图,默认是 R.drawable.loadding
*/
@OptIn(ExperimentalCoilApi::class)
@Composable
fun UrlImage(
modifier: Modifier = Modifier,
url: Any? = null,
@DrawableRes resId:Int? = null,
contentScale: ContentScale = ContentScale.Crop,
) {
val painter = if (resId != null)
painterResource(id = resId)
else {
rememberGlidePainter(request = url,fadeIn = true)
}
Image(
painter = painter,
contentDescription = null,
modifier = modifier,
contentScale = contentScale,
)
}
//Coli 添加依赖 implementation("io.coil-kt:coil-compose:1.4.0") /Coli使用/ Image( painter = rememberCoilPainter( request = "picsum.photos/300/300", requestBuilder = { transformations(CircleCropTransformation()) }, ), contentDescription = stringResource(R.string.image_content_desc), ) Glide和Coli对比 Glide:可以设置动画 并且支持Gif、SVG等格式的图片不需要添加其他依赖库 Coli:Google官网推的网络图片加载库,偶尔会出现图片加载不出来的情况,没有图片的动画
9、在Compose中做屏幕适配
//屏幕适配是通过获取设备屏幕像素
object ScreenConfigInfo {
//设计图宽高px
private const val designWidthDp = 1280f
private const val designHeightDp = 720f
//高度比例
var heightFactor = 0f
//屏幕密度
var scale = 0f
//宽度比例
var widthFactor = 0f
@Composable fun initScreenConfigInfo() { val config = LocalConfiguration.current val widthDp = config.screenWidthDp.toFloat() val heightDp = config.screenHeightDp.toFloat()
scale = config.densityDpi/160f
if (heightFactor == 0f) heightFactor = heightDp / designHeightDp
if (widthFactor == 0f) widthFactor = widthDp / designWidthDp
}
}
//宽度适配
inline val Int.wdp: Dp
get() {
val result = this.toFloat() * widthFactor
return Dp(value = result)
}
//高度适配
@Stable
inline val Int.hdp: Dp
get() {
val result = this.toFloat() * heightFactor
return Dp(value = result)
}
//字体适配
@Stable
inline val Int.spi:TextUnit
get() {
return this* heightFactor.sp
}
//在主题中进行工具类初始化
@Composable
fun HolderStoreAioTheme(
content: @Composable() () -> Unit
) {
//初始化屏幕宽高
ScreenConfigInfo.initScreenConfigInfo()
}
10、在Compose中使用Android原生控件
AndroidView(
//Compose修改器
modifier = Modifier
.fillMaxSize()
.padding(start = 5.wdp),
factory = { context ->
//Android 原生控件
EditText(context).apply {
isFocusable = true
isFocusableInTouchMode = true
showSoftInputOnFocus = false
}
},
update = { view ->
//Android 更新响应
view.setText(text)
view.setTextColor(ContextCompat.getColor(context, R.color.black272727))
view.textSize = 16.spi.value
view.setSelection(text.length)
view.hint = placeHolder
view.setHintTextColor((ContextCompat.getColor(context, R.color.gray9A9A9A)))
// view.setTextCursorDrawable(ContextCompat.getDrawable(context, R.drawable.cursor_color))
view.background = null
if (!isVisible) view.transformationMethod = PasswordTransformationMethod.getInstance()
view.inputType = TYPE_MASK_VARIATION
view.setOnTouchListener { v, event ->
onItemClick()
false
}
}
)