解决ScrollView和ListView冲突问题

yuyu00 2012-05-07

今天项目中需要在ScrollView中嵌套ListView来布局,但是这种布局是Google不提倡的,因为在滚动布局中嵌套一个滚动布局时,会出现外层的滚动布局吃掉内层滚动布局的滚动事件,这样的结果是会出现两种问题:

1、导致内部控件的高度显示不完整,出现只显示部分内容的情况。

2、当内层的ListView内容很多时,外层的ScrollView显示的定位可能不是顶层显示,而是显示底部。

解决办法是参考网上各位大侠的代码而来,本人水平有限,特此记录。

上代码:

布局文件:goodsorder.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/white" >
<ScrollView 
    android:id="@+id/scrollview"
    android:scrollbars="none"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <LinearLayout 
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
	<LinearLayout
		android:id="@+id/sixline"
		android:orientation="vertical"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_margin="5dp"
		>
		<TextView
		    android:id="@+id/cardMessagetext"
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    android:textColor="#000000"
		    android:textSize="16sp"
		    android:textStyle="bold"
		    />
		<TextView
		    android:id="@+id/cardMessage"
		    android:textColor="#000000"
		    android:textSize="14sp"
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    />
	</LinearLayout>
	<ListView 
		android:id="@+id/goodsList"
		android:fillViewport="true"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		/>
    </LinearLayout>
</ScrollView>
</RelativeLayout>
ListView中Item的布局:goodsOrderList.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
	    android:id="@+id/title"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:textColor="#000000"
	    android:textSize="14sp"
	    />
    <TextView
	    android:id="@+id/ordersn"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:textColor="#000000"
	    android:textSize="14sp"
	    />
     <TextView
	    android:id="@+id/orderamounttext"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:textColor="#000000"
	    android:textSize="14sp"
	    android:paddingLeft="20dp"
	    />
    <TextView
	    android:id="@+id/orderamount"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:textColor="#000000"
	    android:textSize="14sp"
	    />
</LinearLayout>

最重要的是代码部分了,下面是主要的代码

public class GoodsOrderActivity extends Activity {
    /** Called when the activity is first created. */
	private ListView goodsView; //商品简单信息显示
	private ScrollView scrollView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.goodsorder);
        SimpleAdapter adapter = new SimpleAdapter(this,getData(),R.layout.goodsOrderList,
				  new String[]{"title","ordersn","orderamounttext","orderamount"},
				  new int[]{R.id.title,R.id.ordersn,R.id.orderamounttext,R.id.orderamount});
	goodsView = (ListView)findViewById(R.id.goodsList);
	goodsView.setAdapter(adapter);

	setListViewHeight(goodsView);//设置listview的高度,在设置adapter之后设置高度
	
        scrollView = (ScrollView)findViewById(R.id.scrollview);

        scrollView.post(runnable);//设置scrollView的显示位置
	}
    /**
     * 设置Listview的高度
     */
    public void setListViewHeight(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(); 
        } 
        ViewGroup.LayoutParams params = listView.getLayoutParams(); 
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
        listView.setLayoutParams(params);
    }
    /**
     * 设置scrollview显示位置,解决scrollview嵌套listview页面过长时显示问题
     */
    private Runnable runnable = new Runnable() {   
    	   
        @Override   
        public void run() {   
        	GoodsOrderActivity.this.scrollView.scrollTo(1,1);// 改变滚动条的位置   
        }   
    }; 
/**
*获取listview数据
*/
private List<Map<String, Object>> getData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		List<Map<String,Object>> cartGoodsList = getCartGoods();
		Map<String, Object> map = new HashMap<String, Object>();
			map.put("orderamounttext", "数量:");
			map.put("ordersn", "价格:");
			map.put("title", "title");
			map.put("orderamount","numberText");
			list.add(map);
		return list; 
}

1、解决显示高度问题思路是:获取ListView中Item每一行的高度,然后算出总高度,最后给ListView设置一下高度,这样系统就知道了ListView的高度。

2、解决显示定位的问题,是设置ScrollView.scrollTo(),但是此方法在onCreate()方法中使用时,必须的另开一个线程,因为此方法,需要在ScrollView中的内容完全加载之后,才会调用,在onCreate()方法没结束之前,ScrollView中的内容是没有完全加载的。

所以需要另开一个线程。

以上观点仅属个人观点,不一定正确,高手莫笑....

相关推荐

ALDRIDGE / 0评论 2011-09-29