ListView和ScrollView都存在滚动的效果,所以一般不建议listView和scrollView进行嵌套使用,但有些需求则需要用到两者嵌套。在android的学习中学了一种事件分发处理机制。
如果listView显示在UI上部,而如imageView等显示在UI下部。
- 首先为listView注册一个滑动监听事件
通过为listView设置固定高度,并注册滑动监听事件。在划动监听事件中,记录用户是否滑动至listView数据底部。
- 通过activity的dispatchTouchEvent()方法进行事件奋发
通过用户记录的是否滑动到listView底部的值在dispatchTouchEvent()方法中进行事件分发处理。
UI :
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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=".MainActivity" > 10 11 <ScrollView 12 android:id="@+id/scrollView1" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:layout_alignParentLeft="true" 16 android:layout_alignParentTop="true" 17 android:layout_alignParentRight="true" 18 android:layout_alignParentBottom="true" 19 > 20 21 <!-- 滚动布局里只能包含一个线性布局 --> 22 <LinearLayout 23 android:layout_width="match_parent" 24 android:layout_height="match_parent" 25 android:orientation="vertical" > 26 27 <ListView 28 android:id="@+id/listView1" 29 android:layout_width="match_parent" 30 android:layout_height="430dp" > 31 </ListView> 32 <ImageView 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:src="@drawable/a"/> 36 <ImageView 37 android:src="@drawable/a" 38 android:layout_width="wrap_content" 39 android:layout_height="wrap_content"/> 40 <ImageView 41 android:src="@drawable/a" 42 android:layout_width="wrap_content" 43 android:layout_height="wrap_content"/> 44 <ImageView 45 android:src="@drawable/a" 46 android:layout_width="wrap_content" 47 android:layout_height="wrap_content"/> 48 49 </LinearLayout> 50 </ScrollView> 51 52 </RelativeLayout>
Activity :
1 package com.example.android_listview_and_scrollview; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.view.Menu; 9 import android.view.MotionEvent; 10 import android.widget.AbsListView; 11 import android.widget.AbsListView.OnScrollListener; 12 import android.widget.ArrayAdapter; 13 import android.widget.ListView; 14 import android.widget.ScrollView; 15 /** 16 * @author xiaowu 17 * NOTE:listView与ScrollView事件冲突处理 18 * 通过Activity的dispatchTouchEvent()方法进行事件分发的处理 19 */ 20 public class MainActivity extends Activity { 21 private ListView listView ; 22 private ScrollView scrollView ; 23 private ArrayAdapter adapter ; 24 private boolean is_move ; 25 private boolean is_scroll_move ; 26 27 @Override 28 protected void onCreate(Bundle savedInstanceState) { 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_main); 31 listView = (ListView)this.findViewById(R.id.listView1); 32 scrollView = (ScrollView)this.findViewById(R.id.scrollView1); 33 adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,getData()); 34 listView.setAdapter(adapter); 35 //为listView添加滚动监听事件 36 listView.setOnScrollListener(new OnScrollListener() { 37 @Override 38 public void onScrollStateChanged(AbsListView view, int scrollState) { 39 // TODO Auto-generated method stub 40 //屏幕移动到底端,并且手已经离开屏幕(用户从ListView滑动到底端) 。OnScrollListener.SCROLL_STATE_IDLE 表示手离开屏幕 41 if(is_move && scrollState==OnScrollListener.SCROLL_STATE_IDLE){ 42 //设置移动状态为true 43 is_scroll_move = true ; 44 } 45 } 46 @Override 47 public void onScroll(AbsListView view, int firstVisibleItem, 48 int visibleItemCount, int totalItemCount) { 49 // TODO Auto-generated method stub 50 is_move = (firstVisibleItem+visibleItemCount == totalItemCount); 51 } 52 }); 53 } 54 public List<String> getData(){ 55 List<String> list = new ArrayList<String>(); 56 for(int i = 0 ;i<20 ;i++){ 57 list.add("ABC"+i); 58 } 59 return list ; 60 } 61 //事件处理机制 62 @Override 63 public boolean dispatchTouchEvent(MotionEvent ev) { 64 // TODO Auto-generated method stub 65 if(ev.getAction()== MotionEvent.ACTION_MOVE){ 66 //想让哪个控件先执行,直接调用哪个控件的dispatchTouchEvent()方法 67 //如果已经拖动到listView的底端,将事件分发给ScrollView 68 if(is_scroll_move){ 69 scrollView.dispatchTouchEvent(ev); 70 }else{ 71 listView.dispatchTouchEvent(ev); 72 } 73 } 74 return super.dispatchTouchEvent(ev); 75 } 76 77 @Override 78 public boolean onCreateOptionsMenu(Menu menu) { 79 // Inflate the menu; this adds items to the action bar if it is present. 80 getMenuInflater().inflate(R.menu.main, menu); 81 return true; 82 } 83 84 }