【Android自定义控件】Kotlin实现滚动效果的数字加减控件

news2024/9/21 2:35:58

前言


因业务上的需要,在APP中点餐时要有商品数目增减操作,数目增减的过程中有翻动的动画效果展现。在Android中有多种方式可以实现,本篇文章记录通过自定义View结合控件的平移动画相结合来实现此需求。


需求分析


在这里插入图片描述

根据上图分析控件的实现过程以及使用到的API,要实现数目上下翻动的效果至少需要两个控件,所以要通过自定义ViewGroup来实现,数字的显示使用TextView控件,实现此控件的前提条件是ViewAViewB控件的大小一致,文字大小和颜色都相同。

1、初始状态,如下图①,默认ViewA所在位置是显示区域,ViewB不可视。

2、数目加1,效果如图②,ViewAViewB同时向上平移一个控件的高度。

3、数目减1,效果如图③,ViewB从上方[ 两倍高度 ]向下平移了一个控件的高度,ViewA从上[ 一倍高度 ]的位置。

4、每一次开始动画前,将要显示的数目值设置到ViewA上,新设置的值设置到ViewB


实现


分析完需求后,可以明确要使用到哪些API,首先是自定义ViewGroup,因为控件ViewAViewB是上下显示,使用ViewGroup.LayoutParams对控件进行初始位置的排布。


class NumberView(context: Context, attributeSet: AttributeSet) :
    FrameLayout(context, attributeSet) {

   	private val viewA: TextView

    private val viewB: TextView

    companion object {
        //向上平移
        const val PAN_UP = 1001
        //向下平移
        const val PAN_DOWN = 1002
		//1前面的数字标识,一位数只传这个,两位数十位传此标识
        const val POS_PRE = "POS_PRE"
        //后面的数字标识,两位数个位穿此标识
        const val POS_NEXT= "POS_NEXT"
    }
    
    /**
     * 平移模式
     */
    private var mode = 0

    
    /**
     * 数字控件宽度
     */
    private var vWidth = 0

    /**
     * 数字控件高度
     */
    private var vHeight = 0

    init {
        LayoutInflater.from(context).inflate(R.layout.layout_number_view, this, true)
        viewA = findViewById(R.id.view_a)
        viewB = findViewById(R.id.view_b)
        initAnim()
    }


    /**
     * 设置字体控件宽高和大小
     */
    fun setSize(w: Int, h: Int, size: Int) {
        if (w == vWidth) { return }
        vWidth = w
        vHeight = h
        textSize = size
        viewA.apply {
            layoutParams =  LayoutParams(vWidth, vHeight)
            gravity = Gravity.CENTER
            textSize = size.toFloat()
        }

        viewB.apply {
            layoutParams = LayoutParams(vWidth, vHeight).apply {
                topMargin = vHeight
            }
            gravity = Gravity.CENTER
            textSize = size.toFloat()
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">

   <TextView
       android:id="@+id/view_a"
       style="@style/number_txt_font"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:gravity="center"
       android:text="@string/number_one"
       android:textColor="@color/color_31" />

   <TextView
       android:id="@+id/view_b"
       style="@style/number_txt_font"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:gravity="center"
       android:textColor="@color/color_31" />

</FrameLayout>

NumberView初始化块中对平移动画进行初始化。


/**
 * 初始化动画
 */
private fun initAnim() {
    animator = ValueAnimator.ofFloat(0f, 1f).apply {
        repeatMode = ValueAnimator.RESTART
        duration = 500
        repeatCount = 0
        interpolator = OvershootInterpolator()
        addUpdateListener {
            val value = it.animatedValue as Float
            startAnim(value)
        }
    }
}
 

ValueAnimatorAndroid 中用于实现动画效果的一个类。允许你在指定的时间段内从一个数值平滑过渡到另一个数值,并且可以监听和响应这个数值变化的过程。

具体参数含义不介绍了,比较简单,创建一个ValueAnimator对象,500ms从0f-1f执行完一次动画,动画执行完成后,初始值还是0f,repeatCount表示只执行一次,使用插值器OvershootInterpolator,表示动画会先超出目标值,然后再回弹到目标值,以增加显示效果。

还需要使用addUpdateListener对动画的进程进行监听,进度值用于控制控件平移的像素值。

控件是向上还是向下平移很好判断,只要拿输入的值和当前值做比较,输入值大于当前值向上平移,小于则向下平移。ViewB设置新的值, ViewA设置旧值,


 /**
  * 设置数字
  */
 fun setNumber(pos: String, newNum: Int) {
     if (number == newNum) { return }
     mode = if (newNum > number) {
         PAN_UP
     } else {
         PAN_DOWN
     }
     //设置旧值
     viewA.text = "$number"
     //设置新值
     viewB.text = "$newNum"
     if (animator?.isRunning == true) {
         animator?.cancel()
     }
     setAnimDelay(pos)
     animator?.duration = 400L + startDelay
     viewA.translationY = 0F
     viewB.translationY = 0F
     animator?.start()
     number = newNum
 }
    
    

 /**
  * 如果是1位数字,立马执行
  * 两位数的数字,设置前后延时执行,产生翻动效果
  */
 private fun setAnimDelay(pos: String) {
     if (pos == POS_FIRST) {
         startDelay = 0
     } else if (pos == POS_SECOND) {
         startDelay = delay
     }
 }
 

控件上下平移使用setTranslationY,用于设置视图(View)在 Y 轴上的平移量。它的作用是将视图在当前的位置基础上沿着 Y 轴进行移动。参数的单位是像素。

正值 : 视图会向下移动。
负值: 视图会向上移动

setTranslationY只会改变视图的视觉位置,并不会影响视图的布局边界(layout bounds)。换句话说,视图的布局位置(例如 top, bottom)不会因为 setTranslationY 而改变,变化只是一个视觉上的移动效果。

开始平移动画,向上平移时viewAViewB同时向上平移一个控件高度的像素值,向下平移时,ViewB从自身相对位置向上两个控件高度,向下平移一个控件高度像素值,ViewA从自身位置向下移动一个控件高度像素值。


/**
 * 开启动画
 */
private fun startAnim(value:Float){
	if (mode == PAN_UP) {
       viewA.translationY = -vHeight * value
       viewB.translationY = -vHeight * value
 	} else {
       viewA.translationY = vHeight * value
       viewB.translationY = -2 * vHeight + vHeight * value
   }
}

布局文件中引用


<com.csdn.ho.NumberView
    android:id="@+id/number"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
    

效果


调用方式这里就不详细说明了,首先设置字体大位置和大小,加减操作时候通过调用setNumber即可。

请添加图片描述

实际项目效果

在这里插入图片描述


总结

本篇文章所实现的自定义效果难度并不大,自定义ViewGroup、使用ValueAnimator,结合ViewsetTranslationY方法实现数字滚动效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2094850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pillow:一个强大的图像处理Python库

我是东哥&#xff0c;一个热衷于探索Python世界的自媒体人。今天&#xff0c;我要向大家介绍一个在Python图像处理领域中不可或缺的库——Pillow。如果你对图像处理感兴趣&#xff0c;或者正在寻找一个简单易用的库来处理图片&#xff0c;那么Pillow绝对是你的不二之选。 基本…

【前端】代码Git提交规范之限制非规范化提交信息

需求背景 在我们目前的前端项目中&#xff0c;我们采用 git 作为版本控制工具。使用 git 管理项目意味着我们经常需要提交代码。当我们执行 git commit -m "描述信息" 命令时&#xff0c;我们被要求提供一个描述信息。现在使用约定式规范提交&#xff0c;和Commitiz…

用纯 div 实现一个选中和未选中状态

在现代网页设计中&#xff0c;利用 div 元素自定义样式&#xff0c;可以让界面更具有吸引力。通过一些简单的 CSS 样式和布局技巧&#xff0c;可以轻松实现交互自然的选中和未选中效果&#xff0c;而不需要依赖传统的 input 元素。 举个 &#x1f330; HTML <body><…

金融POS三层密钥体系 银行卡网络安全系统

银行卡网络安全系统的三层密钥体系 银行卡网络安全系统的三层密钥体系为金融POS系统提供了高度安全的密钥管理。这个体系从上到下分为三层&#xff1a;系统密钥、主密钥、和工作密钥。每一层密钥都负责保护下一层密钥的安全性&#xff0c;确保系统整体的安全性。 三层密钥体系…

[图解]强化自测题解析-总纲(一)01 这属于什么工作流

1 00:00:00,680 --> 00:00:05,350 今天我们开始来解析一些强化自测题 1 00:00:01,100 --> 00:00:03,980 因为现在强化自测题本身 2 00:00:05,010 --> 00:00:06,720 我们出得已经比较多了 3 00:00:07,700 --> 00:00:12,570 自测题是用来测试我们的开发人员 4 00…

华为OD机试真题 - 字符串排序(Python/JS/C/C++ 2024 D卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、…

QT教程-十六,QT中如何解析JSON

一&#xff0c;对json的初步认识 &#xff08;这里我们主要说明最常用的&#xff0c;以一个宏观的概念来说一下&#xff09;&#xff0c;json是一种数据格式&#xff0c;作用就是便于传递信息&#xff0c;我们可以按其结构和对应关系&#xff0c;拿到我们想要的数据。其主要结构…

【专题】2024全球电商消费电子市场研究报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37552 在如今数字经济蓬勃发展的大环境下&#xff0c;电商行业正以前所未有的迅猛之势&#xff0c;对全球商业版图进行着深刻的重塑。据 Stocklytics 发布的有关全球电商市场价值及未来增长趋势的专项调查报告显示&#xff0c;2024…

团队比赛时如何给小组记分?

在团队比赛中&#xff0c;确保每个小组的成绩和排名准确无误是组织者的重要任务。云分组小程序提供了一个便捷的“项目记分”功能&#xff0c;帮助您轻松管理比赛记分过程。以下是如何使用该功能进行团队比赛记分的详细步骤。一、准备工作 1. 打开云分组小程序。 2. 点击“我的…

SQLi-LABS靶场51-55通过攻略

less-51 1.判断注入点 ?sort1 加上单引号会引起报错 2.判断闭合方式 ?sort1-- 可以闭合成功 3.查询数据库名 使用报错注入查询 ?sort1 and updatexml(1,concat(1,database()),1)-- 4.查询数据库的所有表 ?sort1 and updatexml(1,concat(1,(select group_concat(tab…

中锂天源:卡车锂电池的领跑者

随着新能源产业的飞速发展&#xff0c;卡车锂电池市场也呈现出旺盛的生命力。在我国锂电池产业中&#xff0c;中锂天源作为一家专注于新能源锂电池研发与制造的企业&#xff0c;成为了卡车锂电池领域的佼佼者。 中锂天源卡车锂电池采用先进的锂电池技术&#xff0c;具有安全性…

Linux:网络编程之TCP/IP模型,UDP协议

一、OSI模型七层结构 OSI&#xff08;Open Systems Interconnection&#xff09;模型&#xff0c;即开放系统互连参考模型&#xff0c;是一个概念性框架&#xff0c;用于促进全球通信。它定义了网络通信的七层结构&#xff0c;每一层都执行特定的功能&#xff0c;并且每一层都使…

25考研人数预计下降?这一届考研有哪些新趋势?

2025年考研时间线&#xff1a; 2024年9月&#xff1a;公共课及各院校考试大纲公布&#xff1b; 2024年9月下旬&#xff1a;预报名&#xff1b; 2024年10月&#xff1a;正式报名&#xff1b; 2024年11月&#xff1a;线上/线下确认&#xff1b; 2024年12月中下旬&#xff1a…

腾讯版GPT-4o平替方案:VITA

引言 庙内无僧风扫地&#xff0c;寺中少灯月照明。 小伙伴们好&#xff0c;我是微信公众号《小窗幽记机器学习》的小编&#xff1a;买黑神话的小男孩&#xff0c;紧接卖黑神话的小女孩的小作文&#xff0c;今天这篇小作文主要介绍腾讯开源(截至2024年8月25日尚未真正开源&…

【软考】数字签名

目录 1. 说明2. 过程2.1 数字签名过程2.2 数字加密过程 3. 公开密钥4. 报文加密5. 例题5.1 例题1 1. 说明 1.书信或文件是根据亲笔签名或印章来证明其真实性。2.在计算机网络中传送的文电用数字签名来解决问题。3.数字签名必须保证三点&#xff1a;接收者能够核实发送者对报文…

[C语言]第八节 数组一基础知识到高级技巧的全景探索

目录 8.1 数组概念的引入 8.2.⼀维数组的创建和初始化 8.2.1 数组的创建 8.2.2数组的初始化 8.2.3 数组的类型 8.3 ⼀维数组的使⽤ 8.3.1 数组下标 8.3.2 打印数组元素 8.3.3 输入数组元素 8.4 ⼀维数组在内存中的存储 8.5 sizeof计算数组元素个数 8.5.1 sizeof 关键…

第4章-05-用WebDriver下载页面csv到本地

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲,后续完整更新内容如下。 文章…

Java 入门指南:Java 并发编程 —— JMM Java内存模型

JMM&#xff08;Java Memory Model&#xff0c;Java 内存模型&#xff09;&#xff08;抽象模型&#xff09;是用来描述和控制多线程之间内存可见性、有序性、原子性、指令重排等问题的规范。 JMM 定义了一组规则&#xff0c;规定了在多线程环境下&#xff0c;线程在执行共享变…

尚品汇-MQ模块搭建测试、消息不丢失(重)(四十三)

目录&#xff1a; &#xff08;1&#xff09;消息不丢失 &#xff08;2&#xff09;消息确认 &#xff08;3&#xff09;消息确认业务封装 &#xff08;4&#xff09;封装发送端消息确认 &#xff08;5&#xff09;封装消息发送 &#xff08;6&#xff09;发送确认消息测试…

【C#】Visual Studio 2017开发C#,按F1键没有跳转到C#帮助文档,反而跳到了Qt的帮助文档

1. 原因 Visual Studio中安装了Qt的插件&#xff0c;所以将F1的跳转链接转到了Qt的帮助文档。 2. F1改回微软帮助文档方法 工具 - 选项 - Qt - General - Try Qt Documentation when F1 is pressed改为Flase