1. 程式人生 > >解決ScrollView巢狀ListView顯示不完全和滑動衝突的問題

解決ScrollView巢狀ListView顯示不完全和滑動衝突的問題

</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上面就是我的解決方案,還希望各位大牛不吝賜教