listview实现分页加载数据的注意点

注意:listview一旦设置了footerView或者headerView在使用 int count=listView.getAdapter().getCount()-1;代码获取count数时必须减一,不然在使用getItem()报下标越界,二者都有则减二。
1,实现分页时服务器必须提供分页的功能,每次请求传递一个page参数,代表需要加载那一页数据,例如

listview实现分页加载数据的注意点_第1张图片

2,适配器中需新建一个类似如下的方法,以致每次追加数据,list 为需要显示的数据,不应该使用new初始化,而应该在创建listview的activity传递给适配器,不然点击item会崩

public void appendData(List list) {//必须是追加
  this.list.addAll(list);//不能换成this.list=list,这样只会显示当前页,以前的数据会覆盖
  notifyDataSetChanged();
}

3,adpter中提供构造函数和声明,类似如下

private List list = null;
public MessageAdapter(List list) {
  this.list = list;
}

4,在activity中需要提供两个List,其中一个为list 来创建adapter,另一个为appendlist 放每次访问的数据,如果使用同一个,在点击第二页或之后的页,程序会崩。因为在activity中和adapter中同时在改写

listprivate List list ;
//分页的时候得重新创建一个list,不能只创建一个list然后传递给adapter。
// adapter的构造函数必须传递list,且在构造函数中使用this.list=list
// 否则可能出现,1,点击第二屏后的报下标越界2,加载到最后一页界面卡死,任何屏幕操作无效
private List appendlist ;

listView = (ListView) findViewById(R.id.xxx);
adapter = new xxxxAdapter(list);
listView.setAdapter(adapter);

5,访问服务器的代码需放置在一个方法体类,参数有一个page,activity需声明一个变量currentpage=1,每次访问服务器成功得自增1。以便在滚动到底部事件触发调用

private void visitService(int page) {
    if (appendlist.size()>0){//必须将原来的数据清空,否则会将上一次的数据累加 
      appendlist.clear();
    }
    //访问服务器
    //解析数据
    //返回的数据成功的话,执行
    ++currentpage;//前置++和后置++等价时,使用前置++,效率更快
    //appendlist.add(....);
    //调用appendData(appendlist)追加数据
}

6,设置listview的滚动监听事件,并

listView.setOnScrollListener(new AbsListView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {//滚动停止
          if (view.getLastVisiblePosition() == view.getCount() - 1) {
            visitService(currentPage);//调用加载第二页,第三页,...
          }
        }
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
          int totalItemCount) {
      }
    });

7,在创建了listview之后执行第一次访问服务器,取一下数据,比如放在onResume()中

@Override
protected void onResume() {
    super.onResume();
    getRemoteData(1);//访问服务器的方法
}

activity代码如下:  关键代码用绿色字体标注

/**
 * 未读信息list
 */
public class MessageSecondLayerActivity extends Activity implements View.OnClickListener {
    private ListView listView;
    private List list ;
    //分页的时候得重新创建一个list,不能同时创建一个list还把他传递给adapter。
    // adapter的构造函数必须传递list,且在构造函数中使用this.list=list
    // 否则可能出现,1,点击第二屏后的抱越界2,加载到最后一页卡死
    private List appendlist ;
    private ActionBar title;
    private int currentPage;
    private int totalpages;
    private MessageAdapter adapter;
    private TextView footertv,msgNullTv;
    private LinearLayout footer;
    private int MESSAGE=5;
    private String msgType;
    private static String urlString = Urls.base_url + SystemParams.getAppChannel() + "/" + Urls.GETMSGLIST;
    private static String actUrlString=Urls.base_url + SystemParams.getAppChannel() + "/"+Urls.GETACTIVITYLIST;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);
    }

    @Override
    protected void onResume() {
        super.onResume();
        initParams();
        initTitle();
        initlistview();
    }

    private void initParams() {
        currentPage=1;
        totalpages=1;

        list = new ArrayList<>();
        appendlist=new ArrayList<>();

       .....
    }
    private void initTitle() {
          ........
    }

    private void initlistview() {

        footer= (LinearLayout) getLayoutInflater().inflate(R.layout.message_page_end_text, null);
        footertv= (TextView) footer.findViewById(R.id.righttv);
        footertv.setText(getResources().getString(R.string.message_page_end));
        footertv.setGravity(Gravity.CENTER);
        footer.setVisibility(View.INVISIBLE);
        listView = (ListView) findViewById(R.id.smslistview);

        listView.addFooterView(footer,null,false);//必须在setAdapter之前调用

        adapter = new MessageAdapter(list);
        listView.setAdapter(adapter);


        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {//点击item处理
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
               .........
            }
        });

        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {//滚动停止

                    if (view.getLastVisiblePosition() == view.getCount() - 1) {
                        footer.setVisibility(View.VISIBLE);
                        visitSysReplyService(currentPage);
                        if (currentPage==totalpages+1){//分页到底
                            ToastDisplayUtils.ToastCenterDisplay(0,0,"只能显示最近三个月的消息,更多消息请访问底部的网站",MessageSecondLayerActivity.this);

                            footertv.setText(getResources().getString(R.string.message_end));
                        }
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            }
        });
    }
    /**系统消息、问题回复
     * 访问服务器
     * @param page
     */
    private void visitSysReplyService(int page) {
        if (page<=totalpages){
            CommonUtil.showProgressDialog(this, getString(R.string.doing));
            Map params = new HashMap();
            JSONObject jsonObj = new JSONObject();
            try {
                jsonObj.put("token", LoginAccountEntityManager.getInstance().getModelData().getToken());
                jsonObj.put("page", page);//要有类似的参数
                jsonObj.put("size", 10);

               ...
                params.put("params", jsonObj.toString());
                HttpCaller.getInstance().servicePost(urlString, params, new HttpHandler() {
                    public void handleResult(Object result) {
                        try {
                            JSONObject jsonObject = new JSONObject(result.toString());
                            System.out.println("---->"+result.toString());
                            System.out.println(((JSONObject) result).getJSONArray("list").length()>0);
                            if (jsonObject.optBoolean("success")) {
                                if (((JSONObject) result).getJSONArray("list").length()>0) {//防止为空
                                    msgNullTv.setVisibility(View.GONE);
                                    listView.setVisibility(View.VISIBLE);
                                    ++currentPage;
                                    jsonServerData(result);
                                }else{
                                    listView.setVisibility(View.GONE);
                                    msgNullTv.setVisibility(View.VISIBLE);
                                }
                                if (!jsonObject.optString("page").equals("")) {//防止为空
                                    JSONObject pageobject = new JSONObject(jsonObject.optString("page"));
                                    totalpages = pageobject.optInt("totalPages");
                                }
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    public void onAfterHandle(boolean success) {
                        CommonUtil.closeProgressDialog();
                    }
                });
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    }

 .......

    /**解析服务器返回的消息数据
     *
     * @param result
     */
    private void jsonServerData(Object result) {
        if (appendlist.size()>0){//必须带上不然会成倍添加,在滑动过程中出现上下滚动的异常
            appendlist.clear();
        }

        try {
            JSONArray jsonArr = ((JSONObject) result).getJSONArray("list");
            for (int i = 0; i < jsonArr.length(); i++) {
                MessageItem item = new MessageItem();//自定义item bean
                item.setId(jsonArr.getJSONObject(i).getLong("id"));
                item.setMsmcontent(jsonArr.getJSONObject(i).getString("content"));
                Long timemills = new JSONObject(jsonArr.getJSONObject(i).getString("createdOn")).getLong("time");
                item.setMsmDate(timemills);
                item.setTitle(jsonArr.getJSONObject(i).getString("title"));
                item.setMsmstatus(jsonArr.getJSONObject(i).getBoolean("read"));
                item.setMsmType(jsonArr.getJSONObject(i).getString("type"));
                appendlist.add(item);
            }
            adapter.appendData(appendlist);//追加数据

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

   ........
      
}

adapter的代码:
public class MessageAdapter extends BaseAdapter {
    private List list = null;//需要显示的数据,不应该使用new初始化,向上回滚的时候会出问题

    public MessageAdapter(List list) {
        this.list = list;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.messagedetailsitem, null);
        }
       .......//处理

        return convertView;
    }

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

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

    @Override
    public int getCount() {
        return list.size();
    }

    public void appendData(List list) {//分页关键
        this.list.addAll(list);
        notifyDataSetChanged();
    }

  
}

 

 

你可能感兴趣的:(android)