近期項目裏面有個需求,一個頁面放了一個ScrollView,整個頁面可以向上滾動,而後ScrollView裏面又嵌套了一個ListView,ListView裏面的數據也是可以上下滑動的,理論上ListView被包在ScrollView裏面,TouchEvent確定是被ScrollView攔截了。那咱們可以採取什麼思路呢,我看網上很是多作法說是將整個ListView的高度計算出來,感受這樣很是不優雅。假設ListView數據超多。那麼頁面不是超長嗎?當中一個思路就是當咱們滑動ListView區域的時候,ScrollView不要響應OnTouch事件。觸摸ListView區域外的點才幹夠滑動整個頁面。java
給出核心代碼。android
本身定義ScrollViewide
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); } } });