您的位置:首页 > 游戏 > 手游 > 昆明网站建设公司小程序_汕头模板建站代理_网站客服_高端快速建站

昆明网站建设公司小程序_汕头模板建站代理_网站客服_高端快速建站

2024/12/23 1:51:30 来源:https://blog.csdn.net/mhhyoucom/article/details/143978368  浏览:    关键词:昆明网站建设公司小程序_汕头模板建站代理_网站客服_高端快速建站
昆明网站建设公司小程序_汕头模板建站代理_网站客服_高端快速建站

前言

Android Compose实现一个文字跑马灯效果控件;文章最后贴出代码:
1、文字超出后自动滚动
2、使用自定义动画方便修改
3、代码量修改可以根据提供思路自己添加功能。
4、目前只支持横向滚动

关于Compose动画

相比传统布局而言,Compose在各个方面代码量减少,且清晰。

传统布局动画和 Jetpack Compose 动画对比

在 Android 开发中,传统的布局动画和 Jetpack Compose 动画各有优缺点。了解这些差异有助于你根据项目需求选择合适的动画方案。以下是两者的对比分析:

传统布局动画

优势

  1. 兼容性

    • 传统布局动画支持所有版本的 Android,包括较老的设备。
    • 对于需要广泛兼容性的项目,传统动画是一个可靠的选择。
  2. 成熟稳定

    • 传统动画 API 已经存在多年,经过了大量项目的验证,稳定性较高。
    • 社区中有大量的文档和示例可供参考。
  3. 灵活性

    • 传统动画提供了丰富的 API,可以实现复杂的动画效果,如路径动画、关键帧动画等。
    • 可以通过 XML 文件定义动画,方便管理和复用。

劣势

  1. 代码复杂性

    • 传统动画通常涉及多个步骤,如创建 Animator、设置属性、添加监听器等,代码较为冗长。
    • 需要手动管理动画的状态和生命周期,容易出错。
  2. 性能问题

    • 传统动画可能会导致过度绘制,尤其是在复杂的布局中。
    • 动画过程中可能会影响 UI 的响应性,特别是在低端设备上。
  3. 维护成本

    • 由于代码复杂,维护和调试的成本较高。
    • 修改动画效果时,需要修改多处代码,容易引入错误。

Jetpack Compose 动画

优势

  1. 声明式编程

    • Jetpack Compose 采用声明式编程模型,动画代码更加简洁、易读。
    • 可以直接在 Composable 函数中定义动画,逻辑清晰。
  2. 性能优化

    • Compose 的动画系统经过优化,能够高效地处理动画效果,减少不必要的重绘。
    • 动画过程中不会影响其他 UI 组件的性能。
  3. 集成性

    • Compose 动画与 Compose 的其他功能无缝集成,如状态管理、布局等。
    • 可以轻松地组合多个动画效果,实现复杂的动画序列。
  4. 易用性

    • 提供了丰富的内置动画 API,如 animate*AsStateAnimatableCrossfade 等,使用简单。
    • 动画状态和生命周期管理由框架自动处理,开发者只需关注动画效果本身。
  5. 可测试性

    • 由于 Compose 的声明式特性,动画更容易进行单元测试和集成测试。
    • 可以使用 Compose 的测试工具来验证动画的正确性。

劣势

  1. 兼容性

    • Compose 目前仅支持 Android 5.0(API 级别 21)及以上版本。
    • 对于需要支持更老设备的项目,可能需要考虑其他方案。
  2. 学习曲线

    • 对于习惯了传统布局的开发者,Compose 的学习曲线可能较陡峭。
    • 需要时间来适应新的编程范式和概念。
  3. 社区支持

    • 相比传统布局,Compose 的社区支持相对较少,尤其是在解决特定问题时。
    • 文档和示例仍在不断完善中。

总结

  • 传统布局动画

    • 优势:兼容性好、成熟稳定、灵活性高。
    • 劣势:代码复杂、性能问题、维护成本高。
  • Jetpack Compose 动画

    • 优势:声明式编程、性能优化、集成性好、易用性强、可测试性高。
    • 劣势:兼容性限制、学习曲线陡峭、社区支持相对较少。

选择哪种动画方案取决于你的项目需求、目标设备和团队的技术栈。如果你的项目需要广泛的兼容性和复杂的动画效果,传统布局动画可能是更好的选择。如果你追求代码简洁、高性能和易用性,Jetpack Compose 动画则是更佳的选择。

跑马灯组件代码:

@Composable
fun MarqueeText(text: String
) {val density = LocalDensity.currentvar innerBoxWidthDp by remember {mutableIntStateOf(8000) // 再大点就是小说了没有必要跑马灯效果了}var outBoxWidthPx by remember {mutableIntStateOf(0)}var fontWidthPx by remember {mutableIntStateOf(0)}var offsetPx by remember {mutableIntStateOf(0)}var itemOffsetDp by remember {mutableIntStateOf(0)}var itemOffsetDp2 by remember {mutableIntStateOf(0)}LaunchedEffect(key1 = offsetPx) {if (offsetPx > 0 && fontWidthPx > 0) {val itemWidthPx = fontWidthPx + 50var index = 0var index2 = 0var start = offsetPxvar start2 = offsetPx + itemWidthPxval end = -itemWidthPx + offsetPxwhile (true) {itemOffsetDp = with(density) {((start - index).toFloat() / this.density).toInt()}itemOffsetDp2 = with(density) {((start2 - index2).toFloat() / this.density).toInt()}index += 2index2 += 2if ((start - index) < end) {index = 0start = offsetPx + itemWidthPx}if ((start2 - index2) < end) {index2 = 0start2 = offsetPx + itemWidthPx}delay(10)}}}Box(modifier = Modifier.fillMaxWidth().onGloballyPositioned {if (it.size.width != outBoxWidthPx) {outBoxWidthPx = it.size.widthLog.i("TAG_jason", "MarqueeText: change out width")}}.background(Color.LightGray)) {Box(modifier = Modifier.requiredWidth(innerBoxWidthDp.dp).offset(itemOffsetDp.dp)) {Text(modifier = Modifier.widthIn(80.dp).onGloballyPositioned {if (it.size.width != fontWidthPx) {fontWidthPx = it.size.widthinnerBoxWidthDp = with(density) {(fontWidthPx.toFloat() / this.density).toInt()}if (fontWidthPx > outBoxWidthPx) {offsetPx = ((fontWidthPx - outBoxWidthPx).toFloat() / 2).toInt()}Log.i("TAG_jason", "MarqueeText: change font width")}}.wrapContentWidth(),text = text,fontSize = 16.sp,color = Color.Black)}if (offsetPx > 0) {Box(modifier = Modifier.requiredWidth(innerBoxWidthDp.dp).offset(itemOffsetDp2.dp)) {Text(modifier = Modifier.widthIn(80.dp).wrapContentWidth(),text = text,fontSize = 16.sp,color = Color.Red)}}}
}

使用:

class TestVideoPlayer : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {Box(Modifier.fillMaxSize()) {MarqueeText(text = "<------------>再大点就是小说了没有必要跑马灯效果了再大点就是小说了没有必要跑马灯效果了再大点就是小说了没有必要跑马灯效果了再大点就是小说了没有必要跑马灯效果了++++")}}}
}

如果文章对你有用记得点赞啊 !!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com