了解事件分发机制就很容易了解原理,就是在子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到底了","到底了");
}
}
});
复制代码
虽然简单的解决了一下问题但还是存在一些问题 记录下自己接下来再更改。