場景
recyclerivew使用PagerSnapHelper谬泌,子布局中,使用scrollview,觀察逻谦,scrollview內(nèi)容
區(qū)域超過高度時掌实,滑動失效。
原因
recyclerview的觸摸事件邦马,沒有分發(fā)到scrollview中贱鼻,導致了scrollview的觸摸事件失效。
解決方法
(1)當scrollview不需要滑動的時候滋将,無需處理
(2)當scrollview需要滑動的時候邻悬,需要捕獲觸摸事件。對于捕獲的事件后随闽,需要判斷
scrollview是否已經(jīng)處于頂部/底部拘悦,若是,則不再處理觸摸事件橱脸,否則需要處理觸摸事件。
實現(xiàn)
(1)判斷scrollview是否滿足滑動的條件分苇,原理是計算scrollview的子類總高度添诉,再對比當前
scrollview的高度,判斷是否滿足医寿,核心代碼如下:
/**
* 所有子布局高度
*/
private int getChildHeight() {
if (getChildCount() == 0) {
return 0;
}
int result = 0;
for (int i = 0; i < getChildCount(); i++) {
result = result + getChildAt(i).getMeasuredHeight();
}
return result;
}
/**
* 是否有超出內(nèi)容
*/
private boolean outSide() {
return getChildHeight() > getMeasuredHeight();
}
(2)對scrollview進行滑動監(jiān)聽栏赴,初始化滑動到頂部/底部的變量,核心代碼如下:
setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
try {
if (scrollY > oldScrollY) {
// 向下滑動
}
if (scrollY < oldScrollY) {
// 向上滑動
}
if (scrollY == 0) {
// 頂部
// LogUtil.d("PagerSnapScrollView onScrollChange top");
mIsTop = true;
} else {
// LogUtil.d("PagerSnapScrollView onScrollChange top2");
mIsTop = false;
}
if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
//底部
// LogUtil.d("PagerSnapScrollView onScrollChange bottom");
mIsBottom = true;
} else {
// LogUtil.d("PagerSnapScrollView onScrollChange bottom2");
mIsBottom = false;
}
} catch (Exception e) {
}
}
});
(3)最后靖秩,在scrollview的事件分發(fā)中须眷,進行分發(fā)的處理竖瘾,核心代碼如下:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (outSide()) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int endY = (int) ev.getY();
if ((mIsBottom && (mDownY > endY))) {
setDisallowIntercept(false);
return super.dispatchTouchEvent(ev);
}
if ((mIsTop && mDownY < endY)) {
setDisallowIntercept(false);
return super.dispatchTouchEvent(ev);
}
setDisallowIntercept(true);
return super.dispatchTouchEvent(ev);
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
return super.dispatchTouchEvent(ev);
}
setDisallowIntercept(false);
return super.dispatchTouchEvent(ev);
} else {
return super.dispatchTouchEvent(ev);
}
}
that's all------------------------------------