ListView分页加载实现点击加载和手动滑动功能(面试必问)


前言

  • 先介绍一下什么是分页?

以QQ好友列表为例:假如你的好友总共有100个,那么考虑性能等因素,第一次只获取并显示前10条数据。
当用户加载更多时,再去获取后面的10条数据,并与之前的数据合并一起展示给用户。

先来看一下效果图:


使用

下面是代码:
public class MainActivity extends Activity implements OnClickListener, OnScrollListener{
   private ListView                      mLv;
   private List<News>                    list;
   private MyAdapter                     adapter;
   private Button                        mBtn;
   private ProgressBar                   mBar;
   private List<HashMap<String, String>> map;
   private View                          footerview;//底部的视图
   private int maxNum=50;//模拟数据的最大条数
   private int lastVisIdnex;//当前界面最后可见的条目
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      list=new ArrayList<News>();
      mLv=(ListView) findViewById(R.id.mLv);
      footerview=View.inflate(this, R.layout.footerview, null);
      mLv.addFooterView(footerview);//将底部视图添加到listview
      //mLv.addHeaderView(footerview);添加头部视图
      mBtn=(Button) footerview.findViewById(R.id.mBtn);
      mBar=(ProgressBar) footerview.findViewById(R.id.mBar);
      //初始化数据源
      initList();
      adapter=new MyAdapter(this, list);
      mLv.setAdapter(adapter);

      //点击分页加载
//    mBtn.setOnClickListener(this);
      //滑动分页加载
      mLv.setOnScrollListener(this);
   }
   private Handler hand=new Handler(){
      @Override
      public void handleMessage(Message msg) {
         super.handleMessage(msg);
         if(msg.what==0){
            mBar.setVisibility(View.GONE);
            mBtn.setVisibility(View.GONE);
            //调用加载更多的方法,刷新适配器
            loadMore();
            adapter.notifyDataSetChanged();
         }else if (msg.what==1){
            mBar.setVisibility(View.GONE);
            mBtn.setVisibility(View.GONE);
            //调用加载更多的方法,刷新适配器
            loadMore();
            mBtn.setVisibility(View.VISIBLE);
            adapter.notifyDataSetChanged();
         }
      }
   };
   private void initList() {
      for(int i=0;i<10;i++){
         News news=new News();
         news.setTitle("第"+(i+1)+"条数据");
         news.setBody("第"+(i+1)+"条数据");
         list.add(news);
      }
   }
   @Override
   public void onClick(View v) {
      mBtn.setVisibility(View.GONE);
      mBar.setVisibility(View.VISIBLE);
      new Thread(new Runnable() {
         @Override
         public void run() {
            try {
               Thread.sleep(2000);
               //子线程延迟发送一条空消息
               hand.sendEmptyMessage(1);
            } catch (InterruptedException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      }).start();
   }
   //自己写的每次增加多少的方法
   private void loadMore(){
      int count=adapter.getCount();//获得当前总共有多少条目
      if((count+10)<maxNum){
         for(int i=count;i<count+10;i++){
            News nees=new News();
            nees.setTitle("第"+(i+1)+"条数据");
            nees.setBody("第"+(i+1)+"条数据");
            list.add(nees);
         }
      }else{
         //剩余条目不足10条时
         for(int i=count;i<maxNum;i++){
            News nees1=new News();
            nees1.setTitle("第"+(i+1)+"条数据");
            nees1.setBody("第"+(i+1)+"条数据");
            list.add(nees1);
         }
      }

   }
   @Override
   public void onScrollStateChanged(AbsListView view, int scrollState) {
      //当状态更改为点击滑动时把Button按钮隐藏掉
      if (scrollState==SCROLL_STATE_TOUCH_SCROLL){
         mBtn.setVisibility(View.GONE);
      }
      if(scrollState==SCROLL_STATE_IDLE&&lastVisIdnex==adapter.getCount()){
         //确认滑倒底部 加载更多
         mBar.setVisibility(View.VISIBLE);
         mBtn.setVisibility(View.GONE);
         new Thread(new Runnable() {
            @Override
            public void run() {
               try {
                  Thread.sleep(2000);
                  hand.sendEmptyMessage(0);
               } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }

            }
         }).start();
      }
   }
   /*
    * firstVisibleItem:当前界面显示的第一条item的下标,未完全显示也算
    * visibleItemCount:当前界面内显示的item条数(未完全显示的也算)
    * totalItemCount:整个ListView全部的item的条目数
    * */
   @Override
   public void onScroll(AbsListView view, int firstVisibleItem,
                   int visibleItemCount, int totalItemCount) {
      lastVisIdnex=firstVisibleItem+visibleItemCount-1;
      if(totalItemCount==maxNum+1){
         mLv.removeFooterView(footerview);
         Toast.makeText(this, "数据加载完成,无法更新", Toast.LENGTH_SHORT).show();
      }
   }

}

public class MyAdapter extends BaseAdapter{
	private Context ctx;
	private List<News> list;
	public MyAdapter(Context ctx,List<News> list) {
		this.ctx=ctx;
		this.list=list;
	}
	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if(convertView==null){
			holder=new ViewHolder();
			convertView=View.inflate(ctx, R.layout.adapter, null);
			holder.titleTv=(TextView) convertView.findViewById(R.id.titleTv);
			holder.bodyTv=(TextView) convertView.findViewById(R.id.bodyTv);
			convertView.setTag(holder);
		}else{
			holder=(ViewHolder) convertView.getTag();
		}
		holder.titleTv.setText(list.get(position).getTitle());
		holder.bodyTv.setText(list.get(position).getBody());
		return convertView;
	}
	private static class ViewHolder{
		private TextView titleTv,bodyTv;
		
	}
}
public class News {
	private String title;
	private String body;
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getBody() {
		return body;
	}
	public void setBody(String body) {
		this.body = body;
	}
	
	
}

总结

使用Listview的滑动监听方法,然后根据onScrollStateChanged方法里面的状态参数来判断滑动

是否到底部实现加载更多的操作,欢迎大家来学习。

Github地址


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值