实战酷毙了的自定义View(三)

Gtihub传送门

前言

在以前咱们讲到过了PaintCanvas的一些用法,可是其实还不能解决所有问题,在咱们的项目中你是否是有须要这样的东西——滑动和动画。对!!如何实现像RecyclerView的滑动效果,和一个动画效果,接下来咱们将会讲到。git

滑动

其实为了寻求方便,直接使用的是Android已经封装好的类GestureDetector。内部存在一个简单的手势分辨的内部类SimpleOnGestureListener,咱们能够直接调用而后完成滑动这个动做。github

private inner class BarGesture : SimpleOnGestureListener() {

        override fun onDown(e: MotionEvent?): Boolean {
            return true
        }

        override fun onScroll( e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float ): Boolean {
            if (mBarShowNum <= mMinBarScrollShowNum) return false

            val position = dp2px(context, scrollX.toFloat())
            if (distanceX >= 0) {
                if (position <= mBarMaxWidth) {
                    scrollBy(distanceX.toInt(), 0)
                }
            } else {
                if (distanceX >= -1 * position) {
                    scrollBy(distanceX.toInt(), 0)
                }
            }
            return false
        }
    }
复制代码

为了滑动,自动会有一个距离的要求了,咱们调用View已经定义好的ScrollBy,就能够进行挪移了。canvas

整体来讲,其实他已经给咱们封装好了,要作的就是一个方向的判断。另外在代码中咱们能看到scrollX这个变量,这是View已经定义好的一个变量,记住他等等有大用。ide

关于性能

在以前咱们讲到过一个问题,就是Android的坐标系是怎样的。有所遗忘的读者们能够重温一下Android自定义View,你摸的透透的了?对于超出屏幕宽度的图案咱们是否会进行绘制呢?post

咱们对整个绘制作一个测验好了,下面先给出测试代码性能

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // 1
        var count:Int = 0
        for (i in mData!!.indices) {
// if (!checkIsNeedDraw(i)) {
                val height = (mMaxData - mData!![i]) / mMaxData * mBarMaxHeight
                mBarPaint?.shader = null
                drawBarValue(canvas, i, height)
                drawDescriptions(canvas, i)
                mBarPaint?.shader = shader
                drawBars(canvas, height)
                // 2
                count++
// }
            if (i != mData!!.size - 1) {
                canvas?.translate(mBarSingleWidth, 0f)
            }
        }
        // 3
        Log.e("onDraw", count.toString())
    }
复制代码

标注的代码在BarChartView类的源码中加一下就行了。我给出的数据量是7个,那看看结果给出是几回呢!!!学习

Oh my God!!!7次,真的是7次,个人天呐,那不就是说,我超出的部分你也要画????我要你有啥用啊,你别给我画呀。测试

算了算了,知道了要绘制,那咱们就要找解决方案了。咱们刚刚说起到了一个scrollX这个变量,其实就是记录咱们当前屏幕最左边相对于坐标轴而言的,在坐标X轴的哪一个位置了,而屏幕大小又是固定的,那咱们就能够引伸出这样的想法。动画

引伸出的代码以下

private fun checkIsNeedDraw(i: Int): Boolean {
        if (mBarSingleWidth * (i + 1) < scrollX) return true
        if (mBarSingleWidth * i > scrollX + mWidth) return true
        return false
    }
复制代码

看看加了他的效果把。ui

出现了6着数值,说明咱们绘制的数量明显减小了不是。证实方法有效!!!!

动画

动画实际上是一个很大的知识点了,这里不会仔细讲这个,一方面是由于他的知识容量大,一方面是个人接触的还不够全面。

private fun initAnimation() {
        animator = ValueAnimator.ofFloat(0.3f, 1f)
        // 经过插值器来完成动画
        animator?.interpolator = LinearInterpolator()
        animator?.duration = 1500
        animator?.addUpdateListener { animation ->
            scale = animation.animatedValue as Float
            postInvalidate()
        }
    }
复制代码

先来看看个人代码好了。咱们能看到一个LinearInterpolator()这样的玩意儿,定位一下他,就能够看到他的你们族成员有谁了。

经过动画时间的设定,和一个scale也就是值的改变,动态的更改数据,其实也就是不断重绘,来完成咱们所可以看到的逐渐增加的效果。想一想也应该没有这么困难了,你能够直接调用这些类,来完成一些简单的动画效果。

柱状图的绘制

重头戏,重头戏!!!

其实咱们以前已经考虑了不少我在写柱状图的时候遇到的一些问题了,因此大体上的话仍是以看源码为基准,这里主要展现的仍是个人一个设计稿,由于你要去绘制一个柱状图的话,确定是要有必定的计算的。

基本就是靠这个简陋的设计稿完成的个人这个类的了,有Bug请见谅。

不过也一样但愿你能Star一下个人这个项目View_How_To_Make_It

以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。


相关文章推荐:

实战酷毙了的自定义View(二)

实战酷毙了的自定义View(一)

【从零冲击音视频开发】FFmpeg的介绍和基本使用

相关文章
相关标签/搜索