Android Compose笔记

目录

1.组件

1.TextFiled本文输入框

2.点击事件

3.图像

1.渐变色


1.组件

1.TextFiled本文输入框

        TextFiled是MaterialDesign风格的控件,不想要这种风格的时候只能用BaseTextFiled。BaseTextFiled只有一个编辑框功能,没有包括占位符,错误提示功能。

        自定义未输入时文字占位符hint功能:

@Composable
fun MyTextField(
    modifier: Modifier = Modifier,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    textStyle: TextStyle = TextStyle.Default,
    value: String,
    hint: String = "",
    cursorBrush: Brush = SolidColor(Color.Black),
    onValueChange: (String) -> Unit
) {
    BasicTextField(
        value = value,
        onValueChange = onValueChange,
        textStyle = textStyle,
        visualTransformation = visualTransformation,
        cursorBrush = cursorBrush,
        modifier = modifier,
        decorationBox = {
            //必须要保证innerTextField有一次调用
            it.invoke()
            //绘制占位符文本
            if (value.isEmpty())
                Text(
                    text = hint,
                    color = textStyle.color,
                    fontSize = textStyle.fontSize,
                    fontFamily = textStyle.fontFamily,
                    modifier = Modifier.alpha(0.5f)
                )
        }
    )
}

2.点击事件

        传统的View点击事件,我们可以通过继承View,重写OnTouchEvent事件来处理,实现一些效果。

        Compose里要怎么实现?官方文档关于手势的介绍里已经介绍了一些基本方法。

        当前我要实现一个功能,点击控件不松手,控件缩小,松手以后控件恢复原状。

        官方文档的PointerInputScope.detectTapGestures无法实现这个效果。需要通过Modifier.clickable()方法实现。最终代码如下:

@Composable
fun ClickAniText(text:String){
    //控件的缩放大小
    val scale = remember {
        Animatable(1f)
    }
    
    //交互事件源,即之前的touch事件,通过收集交互事件的Flow来处理touch事件
    val interactionSource = remember { MutableInteractionSource() }
    //Flow的收集需要在协程中,使用LaunchedEffect来执行
    LaunchedEffect(key1 = null, block = {
        interactionSource.interactions.collect {
            when (it) {
                is PressInteraction.Press -> {
                    scale.animateTo(0.8f)
                }
                is PressInteraction.Release,
                is PressInteraction.Cancel -> {
                    scale.animateTo(1f)
                }
            }
        }
    })
    
    //绘制文本控件
    Text(
        text = text,
        textAlign = TextAlign.Center,
        modifier = Modifier
            .size(320.dp, 64.dp)
            .clickable(
                interactionSource = interactionSource,
                indication = null,
                onClick = {}
            )
            .scale(scaleX = scale.value, scaleY = scale.value)
            .background(Color.Yellow, shape = RoundedCornerShape(35.dp))
    )
}

代码中用到了Compose的动画,可以去里面看看用法。

2022年1月17日(更新)

以上的实现经过一段时间使用,有一点问题,PressInteraction.Press事件的响应有延迟,体验不是那么好。目前使用Modifier.pointerInteropFilter方法来处理Touch事件,延迟小很多,该方法目前是实验性Api,可能会删除,当前Compose版本1.0.5。

代码示例:

     
    val pressX = remember { mutableStateOf(0f) }
    val pressY = remember { mutableStateOf(0f) }

    Text(
        text = text,
        textAlign = TextAlign.Center,
        modifier = Modifier
            .size(320.dp, 64.dp)
            .pointerInteropFilter { event ->
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        pressX.value = event.rawX
                        pressY.value = event.rawY
                    }
                    MotionEvent.ACTION_UP->{
                        if (
                            abs(event.rawX-pressX.value)<30 &&
                            abs(event.rawY-pressY.value)<30
                        )
                        onClick.invoke()
                    }
                    MotionEvent.ACTION_CANCEL -> {

                    }
                }
                true
            }
            .scale(scaleX = scale.value, scaleY = scale.value)
            .background(Color.Yellow, shape = RoundedCornerShape(35.dp))
    )

3.图像

1.渐变色

如何用Compose实现一个控件的渐变色效果?

通过Canvas来实现渐变色。实现代码如下:

//绘制渐变色
Canvas(
    //Modifier来控制Canvas的绘制范围,这里是充满父控件
    modifier = Modifier
    .fillMaxWidth()
    .fillMaxHeight(),
    onDraw = {
        drawRoundRect(
            brush = Brush.verticalGradient(
                colors = listOf(
                    startColor,
                    endColor
                )
            ),
            cornerRadius = CornerRadius(4.dp.value)
        )
    }
)

2.Canvas

使用Canvas绘制一个Button高光效果:

 

 

@Composable
fun Highlight(
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val image = remember {
        BitmapFactory.decodeResource(context.resources, R.mipmap.icon_task_highlight)
            .asImageBitmap()
    }
    val startOffsetX = LocalDensity.current.run { -103.sdp.toPx() }
    val endOffsetX = LocalDensity.current.run { 200.sdp.toPx() }
    val offsetX = remember {
        Animatable(startOffsetX)
    }
    LaunchedEffect(key1 = null, block = {
        offsetX.animateTo(endOffsetX, repeatable(2, tween(20000)))
    })
    //取消alpha的0.99,可以使image画到Canvas范围之外
    Canvas(modifier = modifier.alpha(0.99f), onDraw = {
        drawImage(
            image = image,
            dstOffset = IntOffset(offsetX.value.toInt(), -31.sdp.roundToPx()),
            dstSize = IntSize(113.sdp.roundToPx(), 179.sdp.roundToPx())
        )
    })
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值