注意:listview一旦设置了footerView或者headerView在使用 int count=listView.getAdapter().getCount()-1;代码获取count数时必须减一,不然在使用getItem()报下标越界,二者都有则减二。
1,实现分页时服务器必须提供分页的功能,每次请求传递一个page参数,代表需要加载那一页数据,例如
2,适配器中需新建一个类似如下的方法,以致每次追加数据,list 为需要显示的数据,不应该使用new初始化,而应该在创建listview的activity传递给适配器,不然点击item会崩
public void appendData(List<MessageItem> list) {//必须是追加
this.list.addAll(list);//不能换成this.list=list,这样只会显示当前页,以前的数据会覆盖
notifyDataSetChanged();
}
3,adpter中提供构造函数和声明,类似如下
private List<MessageItem> list = null;
public MessageAdapter(List<MessageItem> list) {
this.list = list;
}
4,在activity中需要提供两个List,其中一个为list 来创建adapter,另一个为appendlist 放每次访问的数据,如果使用同一个,在点击第二页或之后的页,程序会崩。因为在activity中和adapter中同时在改写
listprivate List<MessageItem> list ;
//分页的时候得重新创建一个list,不能只创建一个list然后传递给adapter。
// adapter的构造函数必须传递list,且在构造函数中使用this.list=list
// 否则可能出现,1,点击第二屏后的报下标越界2,加载到最后一页界面卡死,任何屏幕操作无效
private List<MessageItem> 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<MessageItem> list ;
//分页的时候得重新创建一个list,不能同时创建一个list还把他传递给adapter。
// adapter的构造函数必须传递list,且在构造函数中使用this.list=list
// 否则可能出现,1,点击第二屏后的抱越界2,加载到最后一页卡死
private List<MessageItem> 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<String, String> params = new HashMap<String, String>();
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<MessageItem> list = null;//需要显示的数据,不应该使用new初始化,向上回滚的时候会出问题
public MessageAdapter(List<MessageItem> 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<MessageItem> list) {//分页关键
this.list.addAll(list);
notifyDataSetChanged();
}
}