Kotlin之下拉刷新与上拉加载控件优化

引言


继Kotlin之下拉刷新与上拉加载控件之后,总感觉使用起来体验不是很好且没有增加footerView,这次统一在这里优化。

优化的方面有:增加滑动阻尼、增加footerView等

效果

正文


FooterView

之前由于LinearLayout无法滑动显示出FooterView所以并没有处理,便暂时搁置了。在完成了与ViewPager完美结合的顺滑引导条系列后想到了scrollTo方法,可以通过手势将LinearLayout进行上移。

            when (ev.action) {

                MotionEvent.ACTION_DOWN -> {
                    startY = ev.rawY
                }

                MotionEvent.ACTION_MOVE -> {
                    if (currentState != STATE_LOADING) {
                        val offset = startY - ev.rawY
                        if (offset > 0) {
                            changeState(STATE_DROP_UP)
                            footerView.setVisibleHeight(offset)
                            lastY = offset
                            return true
                        }
                        changeState(STATE_NORMAL)
                    }
                }

                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    lastY = 0f
                    if (currentState == STATE_DROP_UP) {
                        var toState = STATE_NORMAL
                        if (footerView.isEnought()) {
                            toState = STATE_LOADING
                        }
                        changeState(toState)
                    }
                }

            }

这里与HeaderView做了类似的处理,唯一不同的是滑动距离的正负值。由于屏幕坐标原点在左上角,向右向下为正向,下拉时event.rawY是逐渐增加的,所以上滑做了减数与被减数的换位。

至此与HeaderView思路一致,控制LinearLayout滑动的是在FooterView中加了回调,通知RefreshRecyclerView在其内部的FooterView高度变化了多少。

    interface OnAttachViewHeightChangeListener {
        fun onHeightChange(height: Int)
    }

    footerView.onAttachViewHeightChangeListener = object : AttachView.OnAttachViewHeightChangeListener {
        override fun onHeightChange(height: Int) {
            scrollTo(0, height)
        }
    }

AttachView

由于footerView和headerView有相同的方法,因此删除了之前的HeaderView和FooterView,所有统一继承于AttachView

/**
 * Created by mr.lin on 2018/1/16.
 * RefreshRecyclerView 的附加view
 */
abstract class AttachView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : FrameLayout(context, attrs, defStyleAttr) {

    var viewHeight = CommonUtils.dpTopx(50f)
    var onAttachViewHeightChangeListener: OnAttachViewHeightChangeListener? = null

    abstract fun setVisibleHeight(height: Float)

    abstract fun isEnought(): Boolean

    abstract fun start()

    abstract fun end()

    abstract fun cancel()

    interface OnAttachViewHeightChangeListener {
        fun onHeightChange(height: Int)
    }

}

阻尼

简单而言就是让手势的滑动有拉力的感觉,并不是拉一根线而是一根皮筋。

思路:正常的手势滑动 1 -> 5 ->20 ->50
增加阻尼的滑动 1 -> 2 ->5 ->20
数值往后越变大,与前面的差值变化越小,就会感觉明明使了100分的力度结果只走了50分的路程

实现的方法有:负指函数还有偷懒的缩放

负指数:

http://blog.csdn.net/ivan_zgj/article/details/50664780

Kotlin之下拉刷新与上拉加载控件优化_第1张图片

缩放:

    override fun setVisibleHeight(height: Float) {
        var offset = height
        if (offset > width) {
            offset = width.toFloat()
        }
        val params = layoutParams
        params.height = (offset * 0.4).toInt()//阻尼
        layoutParams = params
    }

你可能感兴趣的:(Kotlin之下拉刷新与上拉加载控件优化)