Compose几个简单手势

简介: Compose几个简单手势

概览


Compose提供了多个api用来实现各种手势,这些手势包括点击、按压、双击、长按、水平垂直滑动、拖动、双指平移缩放旋转、嵌套欢动效果


各种手势效果介绍


点击手势

代码

Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Box(modifier = Modifier
            .size(200.dp)
            .background(Color.Green)
            .clickable {
                App.toast("被点击")
            }, contentAlignment = Alignment.Center
        ) {
            Text(text = "点击事件")
        }
    }
复制代码


效果

image.png


单点、按压、双击、长按

代码

@Composable
fun PointerView() {
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Box(
            modifier = Modifier
                .size(200.dp)
                .background(Color.Green)
                .pointerInput(Unit) {
                    detectTapGestures(
                        onTap = {
                            App.toast("单点事件触发")
                        },
                        onDoubleTap = {
                            App.toast("双击事件")
                        },
                        onPress = {
//                            App.toast("按压事件")
                        },
                        onLongPress = {
                            App.toast("长按事件")
                        }
                    )
                }, contentAlignment = Alignment.Center
        ) {
            Text(text = "单点、双击、按压、长按事件")
        }
    }
}
复制代码

说明

双击、单击、长按都会触发按压的效果回调, pointerInput.detectTapGestures

效果

image.png


水平和垂直滑动

代码

val list = (0..255)
    Column(
        Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
    ) {
        Box(
            Modifier
                .fillMaxWidth(10f)
                .height(100.dp)
                .background(Color.Green)
                .horizontalScroll(rememberScrollState()),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = "安安安安卓,欢迎关注掘金号、公众号、csdn,分享android相关知识,安安安安卓,欢迎关注掘金号、公众号、csdn,分享android相关知识,安安安安卓,欢迎关注掘金号、公众号、csdn,分享android相关知识",
                style = TextStyle(color = Color.White, fontSize = 20.sp, fontWeight = FontWeight.Bold)
                )
        }
        repeat(40) {
            Box(
                Modifier
                    .height(80.dp)
                    .fillMaxWidth()
                    .background(Color(list.random(), list.random(), list.random())),
                contentAlignment = Alignment.Center
            ) {
                Text(text = it.toString(), style = TextStyle(color = Color.White, fontSize = 20.sp))
            }
        }
    }
复制代码

说明

任何控件,只需要调用一下两个修饰符就可以实现滑动效果

.verticalScroll(rememberScrollState())

.horizontalScroll(rememberScrollState())


效果

image.png


拖动手势

代码

var offsetX by remember {
        mutableStateOf(0f)
    }
    var offsetY by remember {
        mutableStateOf(0f)
    }
    Box(Modifier.fillMaxSize()) {
        Box(
            Modifier
                .offset { IntOffset(offsetX.toInt(), offsetY.toInt()) }
                .size(200.dp)
                .background(Color.Green, shape = CircleShape)
                .pointerInput(Unit) {
                    detectDragGestures(onDrag = { pointerInputChange: PointerInputChange, offset: Offset ->
                        pointerInputChange.consumeAllChanges()//消费滑动
                        offsetX += offset.x
                        offsetY += offset.y
                    })
                },
            contentAlignment = Alignment.Center
        ) {
            Text(text = "轻按滑动圆")
        }
    }
复制代码

说明

效果

image.png


多段滑动

代码

val list = (0..255)
    val width = 300.dp
    val squareSize = 60.dp
    val swipeableState = rememberSwipeableState(0)
    val sizePx = with(LocalDensity.current) { squareSize.toPx() }
    val anchors = mapOf(
        0f to 0,
        sizePx to 1,
        sizePx * 2 to 2,
        sizePx * 3 to 3,
        sizePx * 4 to 4
    ) // Maps anchor points (in px) to states
    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Row(
            Modifier
                .width(width)
                .height(squareSize)) {
            repeat(5) {
                Box(
                    Modifier
                        .width(squareSize)
                        .fillMaxHeight()
                        .background(color = Color(list.random(), list.random(), list.random()))
                )
            }
        }
        Box(
            modifier = Modifier
                .width(width)
                .swipeable(
                    state = swipeableState,
                    anchors = anchors,
                    thresholds = { _, _ -> FractionalThreshold(0.3f) },
                    orientation = Orientation.Horizontal
                )
        ) {
            Box(
                Modifier
                    .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
                    .width(squareSize)
                    .height(200.dp)
                    .background(Color.Yellow)
            ){
                Text(text = "滑动滑块")
            }
        }
    }
复制代码

说明

这是个实验性质的代码

这里的关键代码如下: 这个anchors会把父容器分为五段,当滑动结束,滑动控件会自动平移到合适的区域位置。

val anchors = mapOf(
        0f to 0,
        sizePx to 1,
        sizePx * 2 to 2,
        sizePx * 3 to 3,
        sizePx * 4 to 4
    )
复制代码

效果

image.png


双指手势(平移、缩放、旋转)

代码

var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *= zoomChange
        rotation += rotationChange
        offset += offsetChange
    }
    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Box(
            Modifier
                // apply other transformations like rotation and zoom
                // on the pizza slice emoji
                .graphicsLayer(
                    scaleX = scale,
                    scaleY = scale,
                    rotationZ = rotation,
                    translationX = offset.x,
                    translationY = offset.y
                )
                // add transformable to listen to multitouch transformation events
                // after offset
                .transformable(state = state)
                .background(Color.Green)
                .fillMaxSize(0.5f),
            contentAlignment = Alignment.Center
        ){
            Text(text = "两指操作,平移,缩放,z轴旋转,单指操作不会有效果", color = Color.White)
        }
    }
复制代码

说明

效果

image.png

嵌套滑动效果

代码

val toolbarHeight = 48.dp//Topbar的高度
    val toolbarHeightPx = with(LocalDensity.current) { toolbarHeight.roundToPx().toFloat() }//topbar高度转换为px
    val toolbarOffsetHeightPx =
        remember { mutableStateOf(0f) }//topbar的动态垂直平移距离
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                val delta = available.y
                val newOffset = toolbarOffsetHeightPx.value + delta//更新topbar的动态平移距离
                toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)//保证topbar的平移距离在(-toolbarHeightPx, 0f)之间
                return Offset.Zero
            }
        }
    }
    Box(
        Modifier
            .fillMaxSize()
            .nestedScroll(nestedScrollConnection)
    ) {
        LazyColumn(contentPadding = PaddingValues(top = toolbarHeight)) {
            items(100) { index ->
                Text("I'm item $index", modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp))
            }
        }
        TopAppBar(
            modifier = Modifier
                .height(toolbarHeight)
                .offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) },
            title = { Text("toolbar offset is ${toolbarOffsetHeightPx.value}") }
        )
    }
复制代码

说明

效果

image.png

git地址:github.com/ananananzhu…



相关文章
|
9月前
|
存储 运维 监控
日志服务SLS焕新升级:卓越性能、高效成本、极致稳定与智能化
日志服务SLS焕新升级,涵盖卓越性能、高效成本、极致稳定与智能化。新功能特性包括Project回收站、ELasticsearch兼容方案及全链路数据处理能力提升。通过扫描计算模式和数据加工优化,实现更好的成本效果。案例分析展示了一家国内顶级车企如何通过日志服务实现跨云、跨地域的全链路数据处理,大幅提升问题处理效率。
232 9
|
7月前
|
人工智能 数据挖掘 Linux
DeepSeek满血版大赏:官方得了“MVP”,第三方是“躺赢狗”?
DeepSeek开源了6710亿参数的R1和2360亿参数的V3两大满血版模型,助力第三方AI平台快速提升性能。此举不仅扩大了DeepSeek的技术影响力,还通过数据飞轮效应优化模型,同时为企业级用户提供灵活变现方式。对于大众,这意味着更多选择、更低使用成本和更快技术迭代。尽管第三方平台可能“阉割”或定制功能,但它们将顶级AI带入更多场景,如比亚迪车机、腾讯元宝等,让AI更普及。官方与第三方各有所长:官方提供最强性能,第三方确保稳定体验。最终,DeepSeek与第三方共同推动AI发展,实现技术普惠。
297 2
|
11月前
|
数据安全/隐私保护
APP备案使用证书查看公钥和md5
【10月更文挑战第19天】首先有了一个证书,文件后缀是keystore
1381 13
APP备案使用证书查看公钥和md5
|
JavaScript 前端开发 Android开发
kotlin开发 webview如何在收到JS调用后,native返回数据给到JS
这段内容描述了在Hybrid App开发中,使用Kotlin的Compose构建的Web视图(WebView)如何通过JsBridge实现JavaScript与原生代码的交互
|
9月前
|
Web App开发 Linux C#
C# 网页截图全攻略:三种技术与 Chrome 路径查找指南
本文主要介绍了在 C# 中实现网页截图的几种技术及相关要点。涵盖了 PuppeteerSharp、Selenium 和 HtmlToImage 三种方式,分别阐述了它们的安装步骤及核心代码。同时,针对在 C# 中寻找 Windows 上 chrome.exe 路径这一问题,分析了未安装 Google Chrome 和已安装两种情况下的查找原因,并给出了相关参考链接,还列举了一系列与 C# 使用 Selenium、获取 chrome.exe 路径以及在 Linux 上部署相关的参考资料。
354 11
|
10月前
|
机器学习/深度学习 存储 人工智能
CRM系统:企业数字化转型的智能引擎
在数字化时代,CRM系统成为企业转型的关键工具,通过集中管理客户信息,提供深度数据分析,助力企业理解客户需求,预测市场趋势,制定有效策略,提升客户满意度。同时,CRM系统支持自动化营销,增强客户互动,提高忠诚度。面对数据安全和跨部门协作的挑战,CRM系统正借助AI技术,迈向智能化,为企业的数字化转型提供强大支持。
|
11月前
|
数据可视化 搜索推荐 数据挖掘
2024年中国CRM系统排名:趋势与领导者
CRM系统在现代商业中至关重要,它不仅提升了客户管理的效率和质量,还通过防止撞单、提高销售团队协作能力和降低销售成本等方式,增强企业的市场竞争力。国内CRM市场中,销售易、白码、悟空等品牌凭借各自优势,为企业提供全面的客户关系管理解决方案,助力企业在激烈的市场竞争中脱颖而出。
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
Android开发 iOS开发
WebView加载https的空白及图片加载不了的问题
WebView加载https的空白及图片加载不了的问题
647 0
|
API Android开发 iOS开发
Android 自定义坐标曲线图
自定义View,使用paint、point、path,画点、点与点连接成线、然后闭合起来就是一个多边形,画坐标,实现坐标曲线图
242 1
Android 自定义坐标曲线图