Android新姿式:能夠下拉/上拉回彈的ListView原理(續)

上一次本身根據原理寫了個下拉ListView,結果如今才發現,其實谷歌的碼神早已經作了相關的實現代碼了!!動畫


但是爲何直接用ListView看不到下拉效果呢?spa


其實這是由於版權的問題,這個下拉的效果是蘋果先出的,你們也都知道蘋果跟谷歌的版權糾紛,因此谷歌雖然也能作到下拉,但沒有明確給出來,只是作了一個動畫效果,就是拉到頂部或底部後繼續拉會有個亮亮的光出現(注意是2.3以後的系統纔有)。繼承


接下來看看谷歌給咱們提供了什麼。it


首先是View類內的overScrollBy方法。原理

    protected boolean overScrollBy(int deltaX, int deltaY,List

            int scrollX, int scrollY,scroll

            int scrollRangeX, int scrollRangeY,方法

            int maxOverScrollX, int maxOverScrollY,im

            boolean isTouchEvent) {lamp

        final int overScrollMode = mOverScrollMode;

        final boolean canScrollHorizontal =

                computeHorizontalScrollRange() > computeHorizontalScrollExtent();

        final boolean canScrollVertical =

                computeVerticalScrollRange() > computeVerticalScrollExtent();

        final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||

                (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);

        final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||

                (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);


        int newScrollX = scrollX + deltaX;

        if (!overScrollHorizontal) {

            maxOverScrollX = 0;

        }


        int newScrollY = scrollY + deltaY;

        if (!overScrollVertical) {

            maxOverScrollY = 0;

        }


        // Clamp values if at the limits and record

        final int left = -maxOverScrollX;

        final int right = maxOverScrollX + scrollRangeX;

        final int top = -maxOverScrollY;

        final int bottom = maxOverScrollY + scrollRangeY;


        boolean clampedX = false;

        if (newScrollX > right) {

            newScrollX = right;

            clampedX = true;

        } else if (newScrollX < left) {

            newScrollX = left;

            clampedX = true;

        }


        boolean clampedY = false;

        if (newScrollY > bottom) {

            newScrollY = bottom;

            clampedY = true;

        } else if (newScrollY < top) {

            newScrollY = top;

            clampedY = true;

        }


        onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);


        return clampedX || clampedY;

    } 


其實View的這個方法已經幫咱們實現了下拉、上拉,甚至左拉右拉都實現了!!

但是爲何ListView繼承了View卻沒有實現下拉呢?


咱們接下來到ListView中的overScrollBy看一下。

protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,

int scrollY, int scrollRangeX, int scrollRangeY,

int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

L.d("deltaX=" + deltaX + ";deltaY=" + deltaY + ";scrollX=" + scrollX

+ ";scrollY=" + scrollY + ";scrollRangeX=" + scrollRangeX

+ ";scrollRangeY=" + scrollRangeY + ";maxOverScrollX="

+ maxOverScrollX + ";maxOverScrollY=" + maxOverScrollY);

return false;


根據我打印的結果,發現後面的maxOverScrollX、maxOverScrollY永遠是0!!

原來如此,谷歌也真是機(jiao)智(hua),代碼明明實現了,就是不明確擺出來,這樣蘋果也無話可說了。


那麼知道了緣由,要實現也下拉也簡單,自定義一個類繼承ListView,重寫overScrollBy方法便可。

protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,

int scrollY, int scrollRangeX, int scrollRangeY,

int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,

scrollRangeX, scrollRangeY, maxOverScrollX,

500, isTouchEvent);

上面的代碼只是給maxOverScrollY硬性的給了個500的值,而後就能夠下拉上拉了,很簡單吧~~


PS:這種方法作出來的下拉ListView效果通常,也沒有下拉刷新功能,若是要用到項目中的話,仍是去找開源的下拉列表吧~~ 

相關文章
相關標籤/搜索