android 开发-ListView与ScrollView事件冲突处理(事件分发机制处理)

时间:2023-03-08 19:55:55
android 开发-ListView与ScrollView事件冲突处理(事件分发机制处理)

  ListView和ScrollView都存在滚动的效果,所以一般不建议listView和scrollView进行嵌套使用,但有些需求则需要用到两者嵌套。在android的学习中学了一种事件分发处理机制。

  如果listView显示在UI上部,而如imageView等显示在UI下部。

  • 首先为listView注册一个滑动监听事件

    通过为listView设置固定高度,并注册滑动监听事件。在划动监听事件中,记录用户是否滑动至listView数据底部。

  • 通过activity的dispatchTouchEvent()方法进行事件奋发

    通过用户记录的是否滑动到listView底部的值在dispatchTouchEvent()方法中进行事件分发处理。

  UI :

 <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
> <!-- 滚动布局里只能包含一个线性布局 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="430dp" >
</ListView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a"/>
<ImageView
android:src="@drawable/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:src="@drawable/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:src="@drawable/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/> </LinearLayout>
</ScrollView> </RelativeLayout>

ListView and ScrollView

  Activity :

 package com.example.android_listview_and_scrollview;

 import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
/**
* @author xiaowu
* NOTE:listView与ScrollView事件冲突处理
* 通过Activity的dispatchTouchEvent()方法进行事件分发的处理
*/
public class MainActivity extends Activity {
private ListView listView ;
private ScrollView scrollView ;
private ArrayAdapter adapter ;
private boolean is_move ;
private boolean is_scroll_move ; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)this.findViewById(R.id.listView1);
scrollView = (ScrollView)this.findViewById(R.id.scrollView1);
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,getData());
listView.setAdapter(adapter);
//为listView添加滚动监听事件
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
//屏幕移动到底端,并且手已经离开屏幕(用户从ListView滑动到底端) 。OnScrollListener.SCROLL_STATE_IDLE 表示手离开屏幕
if(is_move && scrollState==OnScrollListener.SCROLL_STATE_IDLE){
//设置移动状态为true
is_scroll_move = true ;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
is_move = (firstVisibleItem+visibleItemCount == totalItemCount);
}
});
}
public List<String> getData(){
List<String> list = new ArrayList<String>();
for(int i = 0 ;i<20 ;i++){
list.add("ABC"+i);
}
return list ;
}
//事件处理机制
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
if(ev.getAction()== MotionEvent.ACTION_MOVE){
//想让哪个控件先执行,直接调用哪个控件的dispatchTouchEvent()方法
//如果已经拖动到listView的底端,将事件分发给ScrollView
if(is_scroll_move){
scrollView.dispatchTouchEvent(ev);
}else{
listView.dispatchTouchEvent(ev);
}
}
return super.dispatchTouchEvent(ev);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }