我们写一个工程
先看布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<ScrollView
android:id="@+id/sv_scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/ll_linearLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_one"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="#123456"
/>
<GridView
android:layout_width="fill_parent"
android:layout_height="400dp"
android:id="@+id/gv_gridView"
/>
<TextView
android:id="@+id/tv_two"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#234567"
/>
<TextView
android:id="@+id/tv_three"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:background="#345678"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
ScrollView里面嵌套了一个GridView;
现在大家看一下MainActivity代码
package com.example.anjianshijian_chumoshijiandechuli;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridView;
import android.widget.ScrollView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class MainActivity extends Activity implements OnTouchListener {
private GridView gv_gridView;
private List<Map<String, String>> data;
private ScrollView sl_scroll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sl_scroll = (ScrollView) findViewById(R.id.sv_scrollView);
gv_gridView = (GridView) findViewById(R.id.gv_gridView);
gv_gridView.setNumColumns(3);
data = new ArrayList<Map<String, String>>();
for (int i = 0; i < 100; i++) {
Map<String, String> map = new HashMap<String, String>();
map.put("one", "张欣爱我" + i + "生");
data.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this, data,
R.layout.gridview, new String[] { "one" },
new int[] { R.id.tv_adapter });
gv_gridView.setAdapter(adapter);
gv_gridView.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Log.i("张欣", "up");
break;
case MotionEvent.ACTION_MOVE:
Log.i("张欣", "move");
break;
case MotionEvent.ACTION_DOWN:
Log.i("张欣", "down");
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
大家看下效果图
我们知道触摸时间是gv_gridView的,但是我们移动的时候无论如何也无法移动他,100个数据也没办法显示
大家看一下日志,无论你是return false或者是return true都会打印这个结果
只有 down 和move ,没有up;而且随着你的拖拽滑动,move也不再打印输出
要想找原因我们要从sl_scroll上面找;
我们查看下ScrollView里面的秘书方法
public boolean onInterceptTouchEvent(MotionEvent ev){}
我们在移动,拖拽的时候就已经满足了scrollView的action == MotionEvent.ACTION_MOVE和mIsBeingDragged这两个条件,所以事件就被scrollview给拦截消耗了(return true);所以gridview无法得到这个事件;
要想使gridview获得触摸事件,我们要调用scrollview父类的父类ViewGroup的下面的方法
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept)
该方法是设置是否拦截事件
true :事件不拦截 会传递给子控件
false:相反
所以我们要更改下代码
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Log.i("张欣", "up");
break;
case MotionEvent.ACTION_MOVE:
Log.i("张欣", "move");
**在这里添加方法** sl_scroll.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_DOWN:
Log.i("张欣", "down");
break;
default:
break;
}
return super.onTouchEvent(event);
}
我们在运行工程看看日志输出情况
同理,遇到以下事件冲突也可以采用这个方法
ScrollView 嵌套一个GridView
ViewPager 嵌套一个ViewPager
HorizontalScrollView嵌套GridView
ViewPager 嵌套一个ListView GridView
与ScrollView相同 ViewPager, Horizonta,ViewPager也是ViewGroup的直接或者间接子类