Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android ScrollView監聽滑動到頂部和底部的兩種方式(完整的自定義控件實現),androidscrollview

Android ScrollView監聽滑動到頂部和底部的兩種方式(完整的自定義控件實現),androidscrollview

編輯:關於android開發

Android ScrollView監聽滑動到頂部和底部的兩種方式(完整的自定義控件實現),androidscrollview


Android ScrollView監聽滑動到頂部和底部,雖然網上很多資料都有說,但是不全,而且有些細節沒說清楚

 

使用場景:

1. 做一些復雜動畫的時候,需要動態判斷當前的ScrollView是否滾動到底部或者頂部

2. ScrollView滾動到頂部或者底部時主動觸發一些操作(典型的就是滾動到底部觸發自動加載操作)

 

兩種方式:

1. onScrollChanged方式,自己計算

2. onOverScrolled使用系統計算的結果,api >= 9才支持

 

兩種方式如何選擇?

一般來說如果系統有實現的東西,就用系統的,我們畢竟是基於Android系統來做開發,別人做的考慮很多適配兼容問題

所以原則就是系統有就用它的,沒有才用我們自己的,具體實現仔細看代碼,記得看注釋

 

代碼實現,自定義View,可以直接拷貝就可以使用

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

/**
 * 監聽ScrollView滾動到頂部或者底部做相關事件攔截
 *
 */

public class ScanScrollView extends ScrollView {

    private boolean isScrolledToTop = true;  // 初始化的時候設置一下值
    private boolean isScrolledToBottom = false;
    public ScanScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private IScanScrollChangedListener mScanScrollChangedListener;

    /** 定義監聽接口 */
    public interface IScanScrollChangedListener {
        void onScrolledToBottom();
        void onScrolledToTop();
    }

    public void setScanScrollChangedListener(IScanScrollChangedListener scanScrollChangedListener) {
        mScanScrollChangedListener = scanScrollChangedListener;
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        if (scrollY == 0) {
            isScrolledToTop = clampedY;
            isScrolledToBottom = false;
        } else {
            isScrolledToTop = false;
            isScrolledToBottom = clampedY;
        }
        notifyScrollChangedListeners();
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (android.os.Build.VERSION.SDK_INT < 9) {  // API 9及之後走onOverScrolled方法監聽
            if (getScrollY() == 0) {    // 小心踩坑1: 這裡不能是getScrollY() <= 0
                isScrolledToTop = true;
                isScrolledToBottom = false;
            } else if (getScrollY() + getHeight() == getChildAt(0).getHeight()) {
                // 小心踩坑2: 這裡不能是getScrollY() + getHeight() >= getChildAt(0).getHeight()
                isScrolledToBottom = true;
                isScrolledToTop = false;
            } else {
                isScrolledToTop = false;
                isScrolledToBottom = false;
            }
            notifyScrollChangedListeners();
        }
        // 有時候寫代碼習慣了,為了兼容一些邊界奇葩情況,上面的代碼就會寫成<=,>=的情況,結果就出bug了
        // 我寫的時候寫成這樣:getScrollY() + getHeight() >= getChildAt(0).getHeight()
        // 結果發現快滑動到底部但是還沒到時,會發現上面的條件成立了,導致判斷錯誤
        // 原因:getScrollY()值不是絕對靠譜的,它會超過邊界值,但是它自己會恢復正確,導致上面的計算條件不成立
        // 仔細想想也感覺想得通,系統的ScrollView在處理滾動的時候動態計算那個scrollY的時候也會出現超過邊界再修正的情況
    }

    private void notifyScrollChangedListeners() {
        if (isScrolledToTop) {
            if (mScanScrollChangedListener != null) {
                mScanScrollChangedListener.onScrolledToTop();
            }
        } else if (isScrolledToBottom) {
            if (mScanScrollChangedListener != null) {
                mScanScrollChangedListener.onScrolledToBottom();
            }
        }
    }

    public boolean isScrolledToTop() {
        return isScrolledToTop;
    }

    public boolean isScrolledToBottom() {
        return isScrolledToBottom;
    }
}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved