使用Compose实现淘票票选择电影座位的效果

关注公众号学习更多知识


这是一篇去年就写好的博客

起因

新年要来了,看电影是我们新年中必不可少的娱乐项目,那么看电影的时候你是否有想过选座位的空间是如何实现的呢,座位优秀的程序员,我就想到了,今天就带你研究。

compose的绘制系列在两个月前就已经学习完成了,但是仅限于api的熟练,因此今天打算做一个仿淘票票选电影座位的自定义ui。

效果查看

先看一下支付宝客户端的实现吧

我们发现选座位的主要点就是座位的绘制、选择座位的逻辑、双指手势缩放、单指长按后拖动效果。所以关键就是这几个效果的实现

说到这里了提前把我们实现的效果也放出来吧:

实现要点

绘制座位

本身绘制座位我么可以使用drawRoundRect api来实现,不过为了增加难度本例中我们使用path拼接而成的座位。这样做的目标也是为了方便将来将座位扩展成其它形状

构建path的代码:

val path = Path().apply {
        moveTo(boundStart.x, boundStart.y + radius)
        addArc(//绘制圆弧
            Rect(Offset(boundStart.x + radius, boundStart.y + radius), radius),
            180f,
            90f,
        )
        lineTo(boundEnd.x - radius, boundStart.y)
        arcTo(
            Rect(Offset(boundEnd.x - radius, boundStart.y + radius), radius),
            270f,
            90f,
            false
        )
        lineTo(boundEnd.x, boundEnd.y - radius)
        arcTo(Rect(Offset(boundEnd.x - radius, boundEnd.y - radius), radius), 0f, 90f, false)
        lineTo(boundStart.x + radius, boundEnd.y)
        arcTo(Rect(Offset(boundStart.x + radius, boundEnd.y - radius), radius), 90f, 90f, false)
        close()
    }

drawpath:

drawPath(
        path,
        if (seat.type == 0) Color(0xfff4d9bd) else Color(0xffc3d9e9),
        style = Stroke(strokeWidth)//使用Stroke可以保证我们的path绘制出来是线妆的效果
    )
双指操作手势

手势的使用可以参考之前我写过的文章,传送门

使用双指手势需要使用如下两个Modifier操作符:

.graphicsLayer
.transformable(state = state)

实现代码如下:

 var scale by remember { mutableStateOf(1f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *= zoomChange
        offset += offsetChange
    }
    Box(
        Modifier
            .fillMaxSize(),

        contentAlignment = Alignment.Center
    ) {
       内容部分
       ....
    }

代码:https://github.com/ananananzhuo-blog/MovieSeatProject

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值