編輯:關於android開發
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; } }
Android之RecyclerView(二),androidrecyclerview 上篇文章對RecyclerView的使用做了簡單的介紹,本篇文章將繼續介紹。Re
安卓 自定義AlertDialog對話框(加載提示框),安卓alertdialogAlertDialog有以下六種使用方法: 一、簡單的AlertDialog(只顯示一段
Android 自定義View之自繪控件,androidview繪控件首先要提前聲明一下,我對於自定義View的理解並不是很深,最近啃了幾天guolin博主寫的關於自定義
仿UC天氣下拉和微信下拉眼睛頭部淡入淡出--第三方開源--PullLayout,uc--pulllayoutAndroid-PullLayout是github上的一個第三