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