Android ScrollView 嵌套 ListView、 ListView 嵌套ScrollView Scroll事件冲突解决办法
本人菜鸟一名,最近工作了,开始学习Android。
最近在做项目的时候,UX给了个design,大概就是下拉刷新的ListView中嵌套了ScrollView,而且还要在ScrollView中添加动画。
在ListView中嵌套使用ScrollView这种方式是不推荐使用的,但是为了满足UX的设计(UX、QA至上,不然BUG绝逼要来)。
为了解决这个问题,菜鸡开始网上查阅资料,但是搜出来的大多是ListView的Item显示不全等解决方案,并没有解决Scroll事件冲突。通过请教同事,最终使用view的requestDisallow方法成功解决。下面是Demo测试的代码
activity_main.xml
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="com.example.test.MainActivity" > 10 11 <ListView 12 android:id="@+id/list_view" 13 android:layout_width="match_parent" 14 android:layout_height="match_parent" > 15 </ListView> 16 17 </RelativeLayout>
list_view_item.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <ScrollView 7 android:id="@+id/scorll_view" 8 android:layout_width="match_parent" 9 android:layout_height="200dp" > 10 11 <LinearLayout 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:orientation="vertical" > 15 16 <ImageView 17 android:layout_width="match_parent" 18 android:layout_height="100dp" 19 android:contentDescription="@null" 20 android:src="@drawable/ic_launcher" /> 21 22 <ImageView 23 android:layout_width="match_parent" 24 android:layout_height="100dp" 25 android:contentDescription="@null" 26 android:src="@drawable/ic_launcher" /> 27 28 <ImageView 29 android:layout_width="match_parent" 30 android:layout_height="100dp" 31 android:contentDescription="@null" 32 android:src="@drawable/ic_launcher" /> 33 34 <ImageView 35 android:layout_width="match_parent" 36 android:layout_height="100dp" 37 android:contentDescription="@null" 38 android:src="@drawable/ic_launcher" /> 39 </LinearLayout> 40 </ScrollView> 41 42 </RelativeLayout>
ScrollViewItemAdatper.java
1 package com.example.test; 2 3 import android.content.Context; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 9 public class ScrollViewItemAdatper extends BaseAdapter { 10 11 private Context mContext; 12 13 public ScrollViewItemAdatper(Context context) { 14 mContext = context; 15 } 16 17 @Override 18 public int getCount() { 19 return 2; 20 } 21 22 @Override 23 public Object getItem(int arg0) { 24 return arg0; 25 } 26 27 @Override 28 public long getItemId(int arg0) { 29 return arg0; 30 } 31 32 @Override 33 public View getView(int arg0, View arg1, ViewGroup arg2) { 34 if (arg1 == null) { 35 arg1 = LayoutInflater.from(mContext).inflate(R.layout.list_view_item, null); 36 } 37 return arg1; 38 } 39 40 }
MainActivity.java
package com.example.test; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.widget.ListView; public class MainActivity extends Activity { private ListView mListView; private ScrollViewItemAdatper scrollViewItemAdatper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.list_view); scrollViewItemAdatper = new ScrollViewItemAdatper(getBaseContext()); mListView.setAdapter(scrollViewItemAdatper); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { mListView.requestDisallowInterceptTouchEvent(true); return super.dispatchTouchEvent(ev); } }
其中最主要的部分在于
1 @Override 2 public boolean dispatchTouchEvent(MotionEvent ev) { 3 mListView.requestDisallowInterceptTouchEvent(true); 4 return super.dispatchTouchEvent(ev); 5 }
requestDisallowInterceptTouchEvent这个方法是当前的View获得了touch事件是否截取进行处理,从而消耗掉。如果为true的话,这个View就不进行touch事件的处理,转而抛给其子View进行处理。当然,这个只是用来测试的,所以并没有加上许多判断条件。如果在向上或者向下等某个具体手势是,可以使用
dispatchTouchEvent进行判断即可。