1. 程式人生 > >Kotlin之下拉重新整理與上拉載入控制元件優化

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分的路程

實現的方法有:負指函式還有偷懶的縮放

負指數:

縮放:

    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
    }