近期项目里面有个需求,一个页面放了一个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; } }
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); } } });