android密集架移动动画效果开发

机缘

因公司需要开发密集架相关项目,涉及相关项目需求设计,市场上并未有相关动画效果流出,基于设计开发相关需求

多列密集架情况:

  1. 密集架固定列在最左侧
  2. 密集架固定列在最右侧
  3. 密集架固定列在最中间

收获

最终完成初步效果

实例展示:

android密集架移动效果


核心代码

  • 基于需求的复杂性 内部设计是否开启柜体动画,若不开启则直接与硬件通信
  • 密集架向左移动核心代码:
fun moveToLeft(clickedIndex: Int){
        if (isAnimation){
            if (isAir){
                Log.e("TAG","正在通风不可移动")
                Toast.makeText(this,"正在通风不可移动",Toast.LENGTH_SHORT).show()
                return
            }
            if (clickedIndex==fixRow){
                Log.e("TAG","固定列不可移动")
                Toast.makeText(this,"固定列不可移动",Toast.LENGTH_SHORT).show()
                return
            }
            isStop = false
            mBinding.stopTv.text = "停止"
            val childCount = mBinding.llOut?.childCount ?: 0
            if (fixRow==0) { // 固定列在最左侧
                var beginIndex = -1
                for (i in 1 until childCount){
                    var rowBean = allBeans[i]
                    if (rowBean.currentX==rowBean.destX||rowBean.currentX==rowBean.middleX||rowBean.currentX!=rowBean.rawX){ //说明已经移动到位
                        beginIndex = i
                        break
                    }
                }
                if (beginIndex==-1){
                    Log.e("TAG","没有向右移动过不可向左移动")
                    return
                }
                var delay: Long = 0 // 初始延迟时间
                cancleAllAnimation()
                for (i in beginIndex..clickedIndex){
                    var view = mBinding.llOut?.getChildAt(i)
                    var rowBean = allBeans[i]
                    var viewx = view!!.x
                    if (viewx==rowBean.rawX){ //说明已经移回原位
                        continue
                    }
                    allAnimation[i] = ValueAnimator.ofInt(rowBean.currentX.toInt(), rowBean.rawX.toInt())
                    allAnimation[i]?.startDelay = delay
                    allAnimation[i]?.duration = moveTime
                    allAnimation[i]?.addUpdateListener { animation ->
                        val currentValue = animation.animatedValue as Int
                        // 更新视图的左边距,实现平移动画
                        view?.layout(currentValue.toInt(), view.top, (currentValue + view.width).toInt(), view.bottom)
                        // 更新当前 x 坐标
                        rowBean.currentX = view.left.toFloat()
                        Log.e("TAG", "固定列在最左侧 向左移动 实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 左边距 ${view.left}")
                    }
                    allAnimation[i]?.start()
                    delay+=delayAddTime
                }
            }else if (fixRow==childCount-1){ // 固定列在最右侧
                var delay: Long = 0 // 初始延迟时间
                cancleAllAnimation()
                for (i in 0..clickedIndex){
                    var view = mBinding.llOut?.getChildAt(i)
                    var rowBean = allBeans[i]
                    var viewx = view!!.left.toFloat()
                    rowBean.currentX = viewx
                    if (rowBean.currentX==rowBean.destX){ //说明已经移动到位
                        continue
                    }
                    allAnimation[i] = ValueAnimator.ofInt(rowBean.currentX.toInt(), rowBean.destX.toInt())
                    allAnimation[i]?.startDelay = delay
                    allAnimation[i]?.duration = moveTime
                    allAnimation[i]?.addUpdateListener { animation ->
                        val currentValue = animation.animatedValue as Int
                        // 更新视图的左边距,实现平移动画
                        view?.layout(currentValue, view.top, currentValue + view.width, view.bottom)
                        // 更新当前 x 坐标
                        rowBean.currentX = view.left.toFloat()
                        Log.e("TAG", "固定列在右侧 向左移动 实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 左边距 ${view.left}")
                    }
                    allAnimation[i]?.start()
                    delay+=delayAddTime
                }

            }else{ //固定列在中间
                if (clickedIndex<fixRow){ // 点击位置处于固定列左侧 初始只能向左移动 不可向右移动
                    var delay: Long = 0 // 初始延迟时间
                    var beginIndex = 0
                    for (i in fixRow downTo clickedIndex){
                        var rowBean = allBeans[i]
                        if (rowBean.rawX==rowBean.destX){
                            continue
                        }
                        if (rowBean.currentX==rowBean.destX||rowBean.currentX==rowBean.middleX||rowBean.currentX!=rowBean.rawX){
                            beginIndex=i
                            break
                        }
                    }
//                    for (i in beginIndex..clickedIndex){
//                        allAnimation[i]?.let {
//                            it.cancel()
//                        }
//                    }
                    for (i in beginIndex..clickedIndex){
                        var view = mBinding.llOut?.getChildAt(i)
                        var rowBean = allBeans[i]
                        var viewx = view!!.left.toFloat()
                        rowBean.currentX = viewx
                        if (rowBean.currentX==rowBean.destX){ //说明已经移动到位 向左移动 已经移动到目标位置 不可再次向左移动
                            continue
                        }
                        allAnimation[i] = ValueAnimator.ofInt(rowBean.currentX.toInt(), rowBean.destX.toInt())
                        allAnimation[i]?.startDelay = delay
                        allAnimation[i]?.duration = moveTime
                        allAnimation[i]?.addUpdateListener { animation ->
                            val currentValue = animation.animatedValue as Int
                            // 更新视图的左边距,实现平移动画
                            view?.layout(currentValue, view.top, currentValue + view.width, view.bottom)
                            // 更新当前 x 坐标
                            rowBean.currentX = view.left.toFloat()
                            Log.e("TAG", "固定列在右侧 向左移动 实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 左边距 ${view.left}")
                        }
                        allAnimation[i]?.start()
                        delay+=delayAddTime
                    }
                }else{
                    var delay: Long = 0 // 初始延迟时间
                    var beginIndex = clickedIndex
                    for (i in fixRow..clickedIndex){
                        var rowBean = allBeans[i]
                        if (rowBean.rawX==rowBean.destX){
                            continue
                        }
                        if (rowBean.currentX==rowBean.destX||rowBean.currentX==rowBean.middleX||rowBean.currentX!=rowBean.rawX){
                            beginIndex = i
                            break
                        }
                    }
//                    for (i in beginIndex..clickedIndex){
//                        allAnimation[i]?.let {
//                            it.cancel()
//                        }
//                    }
//                    cancleAllAnimation()
                    for (i in beginIndex .. clickedIndex){ // 固定列在中间 从当前点击位置 降序 固定列位置 判断其是否能左移
                        var view = mBinding.llOut?.getChildAt(i)
                        var rowBean = allBeans[i]
                        var viewx = view!!.x
                        if (viewx == rowBean.rawX) { //说明目前在原位置 不可向左移动
                            continue
                        }
                        allAnimation[i] = ValueAnimator.ofFloat(rowBean.currentX, rowBean.rawX) // 向左移动 移动回初始位置
                        allAnimation[i]?.startDelay = delay
                        allAnimation[i]?.duration = moveTime
                        allAnimation[i]?.addUpdateListener { animation -> val currentValue = animation.animatedValue as Float
                            // 更新视图的左边距,实现平移动画
                            view?.layout(currentValue.toInt(), view.top, (currentValue + view.width).toInt(), view.bottom)
                            // 更新当前 x 坐标
                            rowBean.currentX = view.left.toFloat()
                            Log.e("TAG", "实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 平移距离:${view.left}")
                        }
                        allAnimation[i]?.start()
                        delay+=delayAddTime
                    }
                }
            }
        }else{
            //直接向硬件发送指令 向左移动


        }

    }
  • 密集架向右移动核心代码
    fun moveToRight(clickedIndex: Int){
        if (isAnimation){
            if (isAir){
                Log.e("TAG","正在通风不可移动")
                Toast.makeText(this,"正在通风不可移动",Toast.LENGTH_SHORT).show()
                return
            }
            if (clickedIndex==fixRow){
                Log.e("TAG","固定列不可移动")
                Toast.makeText(this,"固定列不可移动",Toast.LENGTH_SHORT).show()
                return
            }
            isStop = false
            mBinding.stopTv.text = "停止"
            val childCount = mBinding.llOut?.childCount ?: 0
            if (fixRow==0){ // 固定列在最左侧
                var delay: Long = 0 // 初始延迟时间
                cancleAllAnimation()
                for (i in childCount-1 downTo clickedIndex){
                    var view = mBinding.llOut?.getChildAt(i)
                    var rowBean = allBeans[i]
                    var viewx = view!!.x
                    if (viewx==rowBean.destX){ //说明已经移动到位
                        continue
                    }
                    allAnimation[i] = ValueAnimator.ofFloat(rowBean.currentX, rowBean.destX)
                    allAnimation[i]?.startDelay = delay
                    allAnimation[i]?.duration = moveTime
                    allAnimation[i]?.addUpdateListener { animation ->
                        val currentValue = animation.animatedValue as Float
                        // 更新视图的左边距,实现平移动画
                        view?.layout(currentValue.toInt(), view.top, (currentValue + view.width).toInt(), view.bottom)
                        // 更新当前 x 坐标
                        rowBean.currentX = view.left.toFloat()
                        Log.e("TAG", "实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 平移距离:${view.left}")
                    }
                    allAnimation[i]?.start()
                    delay+=delayAddTime
                }
            }else if (fixRow==childCount-1){ // 固定列在最右侧
                var delay: Long = 0 // 初始延迟时间
                var beginIndex = -1
                for (i in fixRow downTo clickedIndex){
                    var rowBean = allBeans[i]
                    if (rowBean.currentX==rowBean.destX||rowBean.currentX==rowBean.middleX||rowBean.currentX!=rowBean.rawX){
                        beginIndex = i
                        break
                    }
                }
                cancleAllAnimation()
                for (i in beginIndex downTo clickedIndex){
                    var view = mBinding.llOut?.getChildAt(i)
                    var rowBean = allBeans[i]
                    var viewx = view!!.x
                    if (viewx==rowBean.rawX){ //说明已经移回原位
                        continue
                    }
                    allAnimation[i] = ValueAnimator.ofInt(rowBean.currentX.toInt(), rowBean.rawX.toInt())
                    allAnimation[i]?.startDelay=delay
                    allAnimation[i]?.duration = moveTime
                    allAnimation[i]?.addUpdateListener { animation ->
                        val currentValue = animation.animatedValue as Int
                        // 更新视图的左边距,实现平移动画
                        view?.layout(currentValue, view.top, currentValue + view.width, view.bottom)
                        // 更新当前 x 坐标
                        rowBean.currentX = view.left.toFloat()
                        Log.e("TAG", "固定列在右侧 向左移动实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 左边距 ${view.left}")
                    }
                    allAnimation[i]?.start()
                    delay+=delayAddTime
                }
            }else{ //固定列在中间
                if (clickedIndex<fixRow){
                    var delay: Long = 0 // 初始延迟时间
                    var beginIndex = fixRow
                    for (i in fixRow downTo clickedIndex){
                        var rowBean = allBeans[i]
                        if (rowBean.rawX==rowBean.destX){
                            continue
                        }
                        if (rowBean.currentX==rowBean.destX||rowBean.currentX==rowBean.middleX||rowBean.currentX!=rowBean.rawX){
                            beginIndex=i
                            break
                        }
                    }
//                    cancleAllAnimation()
//                    for (i in beginIndex downTo clickedIndex){
//                        allAnimation[i]?.let {
//                            it.cancel()
//                        }
//                    }
                    for (i in beginIndex downTo clickedIndex){
                        var view = mBinding.llOut?.getChildAt(i)
                        var rowBean = allBeans[i]
                        var viewx = view!!.x
                        if (viewx==rowBean.rawX){ //说明已经移回原位
                            continue
                        }
                        allAnimation[i] = ValueAnimator.ofInt(rowBean.currentX.toInt(), rowBean.rawX.toInt())
                        allAnimation[i]?.startDelay=delay
                        allAnimation[i]?.duration = moveTime
                        allAnimation[i]?.addUpdateListener { animation ->
                            val currentValue = animation.animatedValue as Int
                            // 更新视图的左边距,实现平移动画
                            view?.layout(currentValue, view.top, currentValue + view.width, view.bottom)
                            // 更新当前 x 坐标
                            rowBean.currentX = view.left.toFloat()
                            Log.e("TAG", "固定列在右侧 向左移动实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 左边距 ${view.left}")
                        }
                        allAnimation[i]?.start()
                        delay+=delayAddTime
                    }
                }else{
                    var delay: Long = 0 // 初始延迟时间
//                    cancleAllAnimation()
//                    for (i in childCount-1 downTo clickedIndex){
//                        allAnimation[i]?.let {
//                            it.cancel()
//                        }
//                    }
                    for (i in childCount-1 downTo clickedIndex){
                        var view = mBinding.llOut?.getChildAt(i)
                        var rowBean = allBeans[i]
                        var viewx = view!!.x
                        if (viewx==rowBean.destX){ //说明已经移动到位
                            continue
                        }
                        allAnimation[i] = ValueAnimator.ofFloat(rowBean.currentX, rowBean.destX)
                        allAnimation[i]?.startDelay = delay
                        allAnimation[i]?.duration = moveTime
                        allAnimation[i]?.addUpdateListener { animation ->
                            val currentValue = animation.animatedValue as Float
                            // 更新视图的左边距,实现平移动画
                            view?.layout(currentValue.toInt(), view.top, (currentValue + view.width).toInt(), view.bottom)
                            // 更新当前 x 坐标
                            rowBean.currentX = view.left.toFloat()
                            Log.e("TAG", "实时更新获取当前 view 对象 x 坐标:${rowBean.currentX}    view 平移距离:${view.left}")
                        }
                        allAnimation[i]?.start()
                        delay+=delayAddTime
                    }
                }
            }
        }else{
            //向右移动直接向硬件发送 指令
        }
    }

Tips

  • 柜体移动复杂性涉及多个方面,目前仅android端开发完成,与硬件交互方面同步移动暂未处理(若要实现或许可以通过使用view坐标轴来实现)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有时有晌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值