瞭解事件分發機制就很容易瞭解原理,就是在子view需要處理滑動事件時,父view則不對事件進行攔截處理交由子view進行事件處理,而在父view需要處理時則進行攔截處理,不讓子view處理。
1.首先自定義scrollview,onInterceptTouchEvent方法就是攔截方法,返回true則代表攔截,不讓自view進行處理,返回false,代表讓子view 進行處理。
public class ScrollViewWithListener extends ScrollView {
private ScrollViewListener scrollViewListener;
private onSrcollviewToBottoListener onSrcollviewToBottomListener;
private boolean isBotoom=false;//是否滑動到底部
private boolean isTop=false;//是否內部listview滑動到頂部
public ScrollViewWithListener(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_DOWN) {
Log.v("action_down",ev.toString());
if(isTop&&isBotoom){
Log.v("同時觸及",isTop+""+isBotoom);
return false;
}
return super .onInterceptTouchEvent(ev);
}else if (ev.getAction()==MotionEvent.ACTION_MOVE) {
Log.v("截斷",isTop+""+isBotoom);
if (isTop) {
return super.onInterceptTouchEvent(ev);
}else if (isBotoom) {//如果是底部交由子view處理
return false;
}
} else if(ev.getAction()==MotionEvent.ACTION_UP){
Log.v("action_up",ev.toString());
return false;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(ev);
}
public ScrollViewWithListener(Context context) {
super(context);
}
public ScrollViewWithListener(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
public void setOnToBottomListenr(onSrcollviewToBottomListener onSrcollviewToBottomListener){
this.onSrcollviewToBottomListener=onSrcollviewToBottomListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
View view=getChildAt(getChildCount()-1);
int d=view.getBottom();
d-=getHeight()+getScrollY();
if (d==0){//判斷是否為底部
if (onSrcollviewToBottomListener!=null){
onSrcollviewToBottomListener.onScrollToBottom(true);}
isBotoom=true;
}else {
if (oldy-y!=0){
isBotoom=false;
}
super.onScrollChanged(x, y, oldx, oldy);
}
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
public void setIsTop(boolean istop){
this.isTop=istop;
}
public interface onSrcollviewToBottomListener{
void onScrollToBottom(boolean isBotoom );
}
}
複製程式碼
2.對子view 的listview 滑動監聽。並且回撥結處理結果。
private OnTopListener onTopListener;
private void setScrollViewMoveWhenListViewStopMoving(ListView lv_hot_service) {
lv_hot_service.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState){
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
if (view.getLastVisiblePosition()==(view.getCount()-1)){
Log.v("到底了","到底了");
}
if (view.getFirstVisiblePosition()==0){
onTopListener.viewIsTop(true);
Log.v("vvvvvvvvvv","到頂了"+isListviewTop);
}else {
onTopListener.viewIsTop(false);
Log.v("vvvvvvvvvv","在中間"+isListviewTop);
}
break;
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
onTopListener.viewIsTop(false);
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
onTopListener.viewIsTop(false);
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
public void setOnTopListener(OnTopListener onTopListener){
this.onTopListener=onTopListener;
}
}
複製程式碼
然後將listview的滑動結果傳遞給父view srcollview進行處理。
scrollListener.setOnToBottomListenr(new ScrollViewWithListener.onSrcollviewToBottomListener() {
@Override
public void onScrollToBottom(boolean isBotoom) {
if (isBotoom) {
isListviewTop = false;//記錄到底而讓listview 接管監聽
onTopListener.viewIsTop(false);
Log.v("scrollview到底了","到底了");
}
}
});
複製程式碼
雖然簡單的解決了一下問題但還是存在一些問題 記錄下自己接下來再更改。