最近在写一个聊天的安卓app,用的开源框架是openfire,这个框架还是非常强大的.但是在处理下拉加载聊天记录的时候,还是出现了一些问题。
1,如果使用ASC排序,刷新之前会显示最久的那几条消息,刷新到最后才显示最新消息。使用DESC排序,那么刷新之前最新的聊天会显示在顶部,越往下刷新越会显示越久的消息。这两种方法始终达不到qq聊天的那种效果,后来查了很多资料,也尝试了很多方法,终于得到了解决。
private int chatPosition = 0;//聊天显示的位置
private int end = 5;//每页显示的聊天个数
/** * 设置聊天的Adapter */ private void setChatWindowAdapter() { String selection = ChatProvider.ChatConstants.JID + " = ?"; String[] selectionArgs = {jid}; String orderBy = "_id asc limit (select count(*) from chat)" + (-end) + "," + "(select count(*) from chat)"; new AsyncQueryHandler(mContentResolver) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { ListAdapter adapter = new ChatAdapter(ChatActivity.this, cursor, PROJECTION_FROM); lv_chat.setAdapter(adapter); lv_chat.setSelection(adapter.getCount() - chatPosition); } }.startQuery(0, null, ChatProvider.CONTENT_URI, PROJECTION_FROM, selection, selectionArgs, orderBy); }
*关键是这一句orderBy,它用来处理查询的排序条件,使用ASC排序并且默认显示聊天的个数减去每一页的显示个数到最后的那个聊天个数
,每刷新一次就改变显示的个数,这样就可以达到显示的效果,但是这样刷新,刷新之后会跳到最新条聊天。
2.刷新之后跳到之前消息的位置。
lv_chat.setSelection(adapter.getCount() - chatPosition);这一句代码listview可以跳转到指定位置,再看一看下拉刷新:lv_chat.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() { @Override public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {//下滑 // Toast.makeText(ChatActivity.this, "加载聊天", 0).show(); end += Constant.CHAT_NUM; chatPosition += Constant.CHAT_NUM; Log.d("mmd", end + ""); Log.d("hhh", chatPosition + ""); setChatWindowAdapter(); flag++; new FinishRefresh().execute(); } class FinishRefresh extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void result) { lv_chat.onRefreshComplete(); } } @Override public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {//上滑 } }); }这样处理之后就可以实现聊天,下拉刷新加载历史记录了。