在前面的文章中我们解决了ListView在ScrollView单行显示的问题,但是,当ListView需加载的数据条数很多时(几十,甚至上百条),会发现界面会卡顿很久才显示正常,这是因为原来默认ListView单行,而一下子增加了很多条时ListView的行数会突增,进行setLayoutParams会相当耗资源;尤其是当ScrollView为ViewPager的其中一个页面的时候,切换页面会相当卡。
所以针对这种情况我选择先显示少量几条(界面不会卡了),之后点击最下方的“点击加载更多”(在ListView下方新增加的一个布局),加载布局中有一个加载进度的动画和文字提示(加载中...),再将所有条目显示,这对于用户体验和操作习惯来说是可以接受的,因为点击之后会有加载效果,一般用户会认为“我应该等”,这时候进行耗资源的操作用户也就不会很介意了。
具体实现原理很简单,判断list条数大于3条(具体数目可自行设置)时,先只显示前3条,并显示点击加载的布局,点击之后再将ListView的高度设为所有条数应占的高度,设置完毕后隐藏加载布局就好了(具体流程见代码中注释)。
关键java代码:
listView = (ListView) view.findViewById(R.id.listview); // 获取布局中的listview
myAdapter = new myAdapter(this, StringList); // adapter适配器
listView.setAdapter(myAdapter); // 设置adapter(这里的adapter可以自写)
int totalHeight = 0; // 定义、初始化listview总高度值
for (int i = 0; i < myAdapter.getCount(); i++) {
if (i>2) { //当list条数大于3时则先只显示前3条,即设置高度为3条的高度
setLoadMore(view); //设置加载更多
break;
}
View listItem = myAdapter.getView(i, null, listView); // 获取单个item
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));// 设置item高度为适应内容
listItem.measure(0, 0); // 测量现在item的高度
totalHeight += listItem.getMeasuredHeight(); // 总高度增加一个listitem的高度
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (myAdapter.getCount() - 1)); // 将分割线高度加上总高度作为最后listview的高度
listView.setLayoutParams(params);
void setLoadMore(View view){
loadMoreProgress = (LinearLayout) view.findViewById(R.id.loadmore_progress);
loadMoreProgress.setVisibility(View.VISIBLE); //显示“点击加载更多”的布局(包含一个动画和一段文字)
TextView textView = (TextView) loadMoreProgress.findViewById(R.id.refresh_bom_txt);
textView.setText("点击加载更多");
loadMoreProgress.findViewById(R.id.refbar).setVisibility(View.GONE);//点击之前先隐藏加载进度动画
loadMoreProgress.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.findViewById(R.id.refbar).setVisibility(View.VISIBLE); //显示加载进度动画
TextView textView = (TextView) v.findViewById(R.id.refresh_bom_txt);
textView.setText("加载中...");
ViewGroup.LayoutParams params = listView.getLayoutParams();
int totalHeight = 0;
View listItem = myAdapter.getView(0, null,listView);
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight()*myAdapter.getCount();//设置总高度为完整高度
params = listView.getLayoutParams();
params.height = totalHeight+ (listView.getDividerHeight() * (myAdapter.getCount() - 1));
listView.setLayoutParams(params); //这条语句是最耗资源的,可以用Handler将其放在线程中进行
loadMoreProgress.setVisibility(View.GONE); //设置完毕,隐藏加载布局
}
});
}
布局XML:
<ScrollView
android:id="@+id/scroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fadingEdge="none"
android:scrollbars="none" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/loadmore_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<ProgressBar
android:id="@+id/refbar"
android:layout_width="18dip"
android:layout_height="18dip"
android:layout_gravity="center"
android:indeterminateDrawable="@drawable/user_animation"
android:visibility="gone" />
<TextView
android:id="@+id/refresh_bom_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</ScrollView>