android开发步步为营之65:解决ScrollView和ListView触摸事件onInterceptTouchEvent相互冲突问题

时间:2023-03-08 16:45:50

近期项目里面有个需求,一个页面放了一个ScrollView,整个页面能够向上滚动,然后ScrollView里面又嵌套了一个ListView,ListView里面的数据也是能够上下滑动的,理论上ListView被包在ScrollView里面,TouchEvent肯定是被ScrollView拦截了。那我们能够採取什么思路呢,我看网上非常多做法说是将整个ListView的高度计算出来,感觉这样非常不优雅。假设ListView数据超多。那么页面不是超长吗?当中一个思路就是当我们滑动ListView区域的时候,ScrollView不要响应OnTouch事件。触摸ListView区域外的点才干够滑动整个页面。

给出核心代码。

自己定义ScrollView

package com.figo.study.view;

import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView; public class MyScrollView extends ScrollView {
private OnScrollListener onScrollListener;
private List<View> views = new ArrayList<View>(); public MyScrollView(Context context) {
this(context, null);
} public MyScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
} @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (onScrollListener != null) {
onScrollListener.onScroll(t);
}
} public interface OnScrollListener {
public void onScroll(int scrollY);
} //是否拦截触摸事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (views != null && checkAllViews(views, ev)) {
return false;
}
return super.onInterceptTouchEvent(ev);
} public void addUnTouchableView(View view) {
try {
if (!views.contains(view)) {
views.add(view);
}
} catch (Exception e) {
if (e != null) {
e.printStackTrace();
}
}
} public void delUnTouchableView(View view) {
try {
if (views.contains(view)) {
views.remove(view);
} } catch (Exception e) {
if (e != null) {
e.printStackTrace();
}
}
} public void delAllUnTouchableView() {
try {
if (views.size() > 0) {
views.clear();
} } catch (Exception e) {
if (e != null) {
e.printStackTrace();
}
}
} private boolean checkAllViews(List<View> views, MotionEvent event) {
for (View view : views) {
if (checkInLvArea(view, event)) {
return true;
}
}
return false;
} private boolean checkInLvArea(View v, MotionEvent event) {
try {
float x = event.getRawX();
float y = event.getRawY();
int[] locate = new int[2];
v.getLocationOnScreen(locate);
int l = locate[0];
int r = l + v.getWidth();
int t = locate[1];
int b = t + v.getHeight();
if (l < x && x < r && t < y && y < b) {
return true;
}
return false;
} catch (Exception e) {
if (e != null) {
e.printStackTrace();
}
}
return false; } }

滑动ScrollView后,显示新的页面head的技巧:

        MyScrollView scrollView = (MyScrollView) findViewById(R.id.scrollView);
scrollView.setOnScrollListener(new OnScrollListener() { @Override
public void onScroll(int scrollY) { int top = Math.max(scrollY, mLayoutHead.getTop()/2);
mLayoutHeadNew.layout(0, top, mLayoutHeadNew.getWidth(), top + mLayoutHeadNew.getHeight());
if(scrollY>=canScrollHeight)
{
// mLayoutHead.setVisibility(View.GONE);
mLayoutHeadNew.setVisibility(View.VISIBLE);
}else
{
// mLayoutHead.setVisibility(View.VISIBLE);
mLayoutHeadNew.setVisibility(View.GONE);
}
}
});