1. 程式人生 > >Android開發中控制ScrollView直接滾動到頂部或底部

Android開發中控制ScrollView直接滾動到頂部或底部

場景:開發的過程,如果一個頁面子View比較多,一個螢幕放不下,此時我們大多會採用ScrollView來實現。然後產品可能會提這種需求,比如某個子View在最底部,產品想要頁面進入就直接滑到最底部;或者是當頁面滑到最底部時,點選某個按鈕直接滑到頂部。

還是先呈上方法,然後再來具體分析

mScrollView.fullScroll(ScrollView.FOCUS_UP);//滑到頂部
mScrollView.fullScroll(ScrollView.FOCUS_DOWN);//滑到底部

為什麼可以實現這種效果,我們來看下fullScroll()這個方法的原始碼

/**
  * <p>Handles scrolling in
response to a "home/end" shortcut press. This * method will scroll the view to the top or bottom and give the focus * to the topmost/bottommost component in the new visible area. If no * component is a good candidate for focus, this scrollview reclaims the * focus.</p> * * @param direction the
scroll direction: {@link android.view.View#FOCUS_UP} * to go the top of the view or * {@link android.view.View#FOCUS_DOWN} to go the bottom * @return true if the key event is consumed by this method, false otherwise */ public boolean fullScroll(int direction) { boolean
down = direction == View.FOCUS_DOWN; int height = getHeight(); mTempRect.top = 0; mTempRect.bottom = height; if (down) { int count = getChildCount(); if (count > 0) { View view = getChildAt(count - 1); mTempRect.bottom = view.getBottom() + mPaddingBottom; mTempRect.top = mTempRect.bottom - height; } } return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom); }

這裡我們可以看到實際上是呼叫了scrollAndFocus()方法,繼續來看原始碼

/**
  * <p>Scrolls the view to make the area defined by <code>top</code> and
  * <code>bottom</code> visible. This method attempts to give the focus
  * to a component visible in this area. If no component can be focused in
  * the new visible area, the focus is reclaimed by this ScrollView.</p>
  *
  * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
  *                  to go upward, {@link android.view.View#FOCUS_DOWN} to downward
  * @param top       the top offset of the new area to be made visible
  * @param bottom    the bottom offset of the new area to be made visible
  * @return true if the key event is consumed by this method, false otherwise
  */
    private boolean scrollAndFocus(int direction, int top, int bottom) {
        boolean handled = true;

        int height = getHeight();
        int containerTop = getScrollY();
        int containerBottom = containerTop + height;
        boolean up = direction == View.FOCUS_UP;

        View newFocused = findFocusableViewInBounds(up, top, bottom);
        if (newFocused == null) {
            newFocused = this;
        }

        if (top >= containerTop && bottom <= containerBottom) {
            handled = false;
        } else {
            int delta = up ? (top - containerTop) : (bottom - containerBottom);
            doScrollY(delta);
        }

        if (newFocused != findFocus()) newFocused.requestFocus(direction);

        return handled;
    }

看到這裡就很明白了吧,最終是呼叫doScrollY()這個方法,所以能夠實現滑動到頂部或者底部的效果

還沒有結束,重點在這裡,請仔細看完 - - ->

fullScroll()這個方法不能直接被呼叫,因為Android中的佈局載入需要時間(跟佈局的巢狀度以及頁面的複雜度等都有關),頁面建立不等於view馬上就會顯示,而是在等待繪製完成,雖然很快,但是如果立即呼叫fullScroll(),此時view可能還沒有完成,這樣就會報異常,應該通過handler來呼叫fullScroll(),具體程式碼如下:

new Handler().post(new Runnable() {
            @Override
            public void run() {
                mScrollView.fullScroll(ScrollView.FOCUS_UP);//滑到頂部
                //mScrollView.fullScroll(ScrollView.FOCUS_DOWN);//滑到底部
            }
        });