XScrollView 內部重寫 onScrollChanged 並回調接口,但外部 setOnScrollListener 設置的監聽器方法不執行,斷點進入內部回調卻不進入外部實現。
接口回調對象為空或未正確傳遞。常見情況:
XScrollView 構造函數未將外部傳入的 Listener 保存到成員變數。this(context, attrs),導致屬性初始化邏輯漏執行。setOnScrollListener 方法未正確賦值給成員變數。
public class XScrollView extends ScrollView {
private OnScrollListener scrollListener; // 成員變數持有引用
// 所有構造函數必須鏈式調用
public XScrollView(Context context) { this(context, null); }
public XScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
public XScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(); // 統一初始化
}
private void init() { /* 可在此初始化手勢檢測等 */ }
// 關鍵:正確賦值
public void setOnScrollListener(OnScrollListener listener) {
this.scrollListener = listener;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollListener != null) { // 非空判斷
scrollListener.onScroll(l, t, oldl, oldt);
// 可選:檢測到達底部
if (t + getHeight() >= getChildAt(0).getHeight())
scrollListener.onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE, true);
}
}
public interface OnScrollListener {
int SCROLL_STATE_IDLE = 0;
void onScroll(int l, int t, int oldl, int oldt);
void onScrollStateChanged(ScrollView view, int scrollState, boolean arriveBottom);
}
}
XScrollView scrollView = findViewById(R.id.xscroll);
scrollView.setOnScrollListener(new XScrollView.OnScrollListener() {
@Override
public void onScroll(int l, int t, int oldl, int oldt) {
Log.d("TAG", "滑動中: l=" + l + ", t=" + t);
}
@Override
public void onScrollStateChanged(ScrollView view, int scrollState, boolean arriveBottom) {
if (arriveBottom) Log.d("TAG", "到達底部");
}
});
implementation 'com.huxq17.xrefreshview:xrefreshview:3.5.5'
**建議直接使用官方庫最新版**,自帶完善的滑動監聽,避免手動複製源碼引入 Bug。