</pre>在开发中我们往往会遇到这样奇葩的需求,让一个ScrollView嵌套ListView,那么我们就会遇到这样一个问题,就是listView 显示不完全和滚动冲突的问题。下面就来解决一下这个问题</p><p></p><p>首先看一下布局</p><p></p><pre class="html" name="code"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="点击" />
<TextView
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="@android:color/holo_blue_bright"
android:text="我是上面的布局"
android:textSize="20sp" />
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="200dp" >
</ListView>
<TextView
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@android:color/holo_red_dark"
android:text="我是下面的布局"
android:textSize="20sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
不做任何处理默认显示listView只有一个条目,那么我使用的解决方案在xml文件中将listView的高度写死
还有一些其他的方法:常用的是测量listView的子View的高度,然后重新绘制View
下面将源码附上
private void setListViewHeightBasedOnChildren(ListView listview) {
ListAdapter listAdapter = listview.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listview);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
LayoutParams params = listview.getLayoutParams();
params.height = totalHeight
+ (listview.getDividerHeight() * (listAdapter.getCount() - 1));
params.height += 5;// if without this statement,the listview will be a
// little short
// 将测量的高度设置给listView
listview.setLayoutParams(params);
}
下面就是解决listView和ScrollView的滑动冲突的问题了。很明显这个就需要用到事件分发的知识了
设置listView的触摸监听,然后在触摸事件里面处理逻辑,当触摸的时候请求listView的父亲不要去拦截这个事件,将事件传递下来让lsitView来处理
具体实现方式:
lv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
scrollView.requestDisallowInterceptTouchEvent(false);
} else {
// 请求父类不要拦截这个事件或者直接让ScrollView不拦截这个事件,下面的两行代码一样
// lv.getParent().getParent().requestDisallowInterceptTouchEvent(true);
scrollView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
OK上面就是我的解决方案,还希望各位大牛不吝赐教