最近在開發一個應用時用到了ScrollView和ListView,想在ListView上再放一個小的標題欄分割,然後整體超出屏幕後又能滾動顯示。但是,在跟蹤過程中發現,我們自己設置了ListViewAdapter後,getView(int position, View convertView, ViewGroup parent)函數雖然一直在調用,position卻一直是0。然後在顯示界面只能看到一個Item。而eclipse會提示“The vertically scrolling ScrollView should not contain another vertically scrolling widget (ListView)”。
剛開始想想既然兩種View衝突,那我去掉ScrollView吧,但是效果出來自測後發現,當ListView超出屏幕範圍,界面根本都不會滾動顯示,看來這個問題繞不過去了。在網上搜了下,發現並驗證以下方法解決了,據說最早是在stackoverflow上最早有人解決的,有興趣的可以多去逛逛。
好,春花,上代碼~
1、新增文件ListViewRelayout.java。
public class ListViewRelayout {
public void setListViewHeightBasedOnChildren(ListView listView) {
// get the list view adapter, so this function must be invoked after set the adapter.
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
// get the ListView count
int count = listAdapter.getCount();
for (int i = 0; i < count; i++) {
View listItem = listAdapter.getView(i, null, listView);
// measure the child view
listItem.measure(0, 0);
// calculate the total height of items
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
// get divider height for all items and add the total height
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}
2、在ListActivity.java
mAppListView.setAdapter(mAppListAdapter);
mRelayout.setListViewHeightBasedOnChildren(mAppListView);
如果你還增加了對ListView的動態改變,那麼,還需要在notifyDataSetChanged後再調用一次,如:
mEnableAppListAdapter.notifyDataSetChanged();
mUtil.setListViewHeightBasedOnChildren(mEnableAppListView);
這樣我們的ListView的LayoutParam就會重新被設置,從而界面刷新時能看到全部顯示的ListView。
對notifyDataSetChanged()感興趣的同學可參考本博客另一篇文章《如何動態刷新ListView的顯示---notifyDataSetChanged》,敬請關注。