ListView是Android中经常用到的一个控件,用来以列表的形式展示数据,但是当数据量过大时,会出现数据加载过慢,甚至是失去响应,我们可以用分页显示来处理这个问题。
下面的代码是我结合网上的资源整合的结果,感谢网友们的无私奉献!
实现思路,主要是监听scroll事件,加载新数据。
下面是代码:
package com.ns.pagelist;
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.AbsListView.OnScrollListener; public class PagesListActivity extends Activity implements OnClickListener,OnScrollListener{ private ListView pageListView; private Button btnPre; private Button btnNext; private PageAdapter pageAdapter;// private static int laseItem = 0; private static int nowpage = 1; private List<Map<String, Object>> mData; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pageListView = (ListView)findViewById(R.id.page_list); btnPre = (Button)findViewById(R.id.buttonPre); btnNext = (Button)findViewById(R.id.buttonNext); //构建Loading布局 LinearLayout searchLayout = new LinearLayout(this); // 水平方向的线性布局 searchLayout.setOrientation(LinearLayout.HORIZONTAL); // 添加进度条 ProgressBar progressBar = new ProgressBar(this); progressBar.setPadding(0, 0, 15, 0); searchLayout.addView(progressBar, new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); // 添加文字,设置文字垂直居中 TextView textView = new TextView(this); textView.setText("加载中..."); textView.setGravity(Gravity.CENTER_VERTICAL); searchLayout.addView(textView, new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); // 同时将进展条和加载文字显示在中间 searchLayout.setGravity(Gravity.CENTER); LinearLayout loadingLayout = new LinearLayout(this); loadingLayout.addView(searchLayout, new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); loadingLayout.setGravity(Gravity.CENTER); // 加载到listActivity的底部 pageListView.addFooterView(loadingLayout); pageListView.setOnScrollListener(this); mData = getData(); pageAdapter = new PageAdapter(this); pageListView.setAdapter(pageAdapter); btnPre.setOnClickListener(this); btnNext.setOnClickListener(this); checkButton(); } //点击左边的Button,表示向前翻页,索引值要减1. public void leftView(){ nowpage--; for (int i = 0; i < 10; i++) { mData.remove(mData.size() - 1); } //刷新ListView里面的数值。 pageAdapter.notifyDataSetChanged(); pageListView.setSelection((nowpage - 1)*10 + 1); //检查Button是否可用。 checkButton(); } //点击右边的Button,表示向后翻页,索引值要加1. public void rightView(){ nowpage++; mData.addAll(getData()); //刷新ListView里面的数值。 pageAdapter.notifyDataSetChanged(); pageListView.setSelection((nowpage - 1)*10 + 1); //检查Button是否可用。 checkButton(); } public void checkButton(){ //索引值小于等于1,表示不能向前翻页了,以经到了第一页了。 //将向前翻页的按钮设为不可用。 if(nowpage <=1){ btnPre.setEnabled(false); } /*//值的长度减去前几页的长度,剩下的就是这一页的长度,如果这一页的长度比View_Count小,表示这是最后的一页了,后面在没有了。 //将向后翻页的按钮设为不可用。 else if(data.length - index*viewCount <= viewCount){ btnNext.setEnabled(false); }*/ //否则将2个按钮都设为可用的。 else { btnPre.setEnabled(true); btnNext.setEnabled(true); } } //自定义Adapter class PageAdapter extends BaseAdapter{ private LayoutInflater mInflater; public PageAdapter(Context context) { this.mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { return position; } public final class ViewHolder { public ImageView img; public TextView title; public TextView info; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.mylistitem, null); holder.img = (ImageView) convertView.findViewById(R.id.img); holder.title = (TextView) convertView.findViewById(R.id.title); holder.info = (TextView) convertView.findViewById(R.id.info); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.img.setBackgroundResource((Integer) mData.get(position).get("img")); holder.title.setText((String) mData.get(position).get("title")); holder.info.setText((String) mData.get(position).get("info")); return convertView; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.buttonPre: leftView(); break; case R.id.buttonNext: rightView(); break; } } //监听Scroll事件,实现分页显示的关键 @Override public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) { //获取当前页面最后一条数据的位置 laseItem = firstVisibleItem + visibleItemCount - 1; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //如果用户已经滚到最后一条数据,并且已经松手,则加载新的数据 if (laseItem == pageAdapter.getCount() && scrollState == OnScrollListener.SCROLL_STATE_IDLE) { nowpage++; mData.addAll(getData()); pageAdapter.notifyDataSetChanged(); checkButton(); } } private List<Map<String, Object>> getData() { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); for (int i = 0; i < 10; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("title", nowpage + "ItEye" + (i + 1)); map.put("info","独立之人格,自由之思想,如果视图正在滚动,此方法将被调用之前,滚动下一帧呈现。特别是,它会被调用之前调用getView。。。。。" + (i + 1)); map.put("img", R.drawable.ic_launcher); list.add(map); } return list; } }
下面是运行后的截图: