android实现listview分页的方法

本文实例讲述了android实现listview分页的方法。分享给大家供大家参考。具体分析如下:

最近做了下listview的分页,跟WEB上的分页是一个意思,需要那几个分页参数,不同的是sqlite中分页的查询语句,简便的方法需要用Limit,Offset关键字,前者是查询每页展示的记录数,后者是越过多少记录数,说得明白点就是忽略前面多少行记录之后,取多少行记录

我分页采用了一个重要的类Page,通过封装Page类,做为参数传递进来,返回出去也是个Page对象

import java.util.Collections;
import java.util.List;
/**
 * 注意所有序号从1开始.
 *
 * @param <T> Page中记录的类型.
 *
 */
public class Page<T> {
  //-- 公共变量 --//
  public static final String ASC = "asc";
  public static final String DESC = "desc";
  //-- 分页参数 --//
  protected int pageNo = 0;// 当前页号<跟取数据的方式有关系>
  protected int pageSize = 1;// 每页显示的记录数
  protected String orderBy = null;
  protected String order = null;
  protected boolean autoCount = true;
  //-- 返回结果 --//
  protected List<T> result = Collections.emptyList();
  protected long totalCount = -1;// 总记录数
  //-- 构造函数 --//
  public Page() {
  }
  public Page(final int pageSize) {
    setPageSize(pageSize);
  }
  public Page(final int pageSize, final boolean autoCount) {
    setPageSize(pageSize);
    setAutoCount(autoCount);
  }
  //-- 访问查询参数函数 --//
  /**
   * 获得当前页的页号,序号从0开始,默认为0.
   */
  public int getPageNo() {
    return pageNo;
  }
  /**
   * 设置当前页的页号,序号从0开始,低于0时自动调整为0.
   */
  public void setPageNo(final int pageNo) {
    this.pageNo = pageNo;
    if (pageNo < 0) {
      this.pageNo = 0;
    }
  }
  /**
   * 获得每页的记录数量,默认为1.
   */
  public int getPageSize() {
    return pageSize;
  }
  /**
   * 设置每页的记录数量,低于0时自动调整为0.
   */
  public void setPageSize(final int pageSize) {
    this.pageSize = pageSize;
    if (pageSize < 0) {
      this.pageSize = 0;
    }
  }
  /**
   * 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从0开始.
   */
  public int getFirst() {
    return (pageNo * pageSize) + 1;
  }
  /**
   * 获得排序字段,无默认值.多个排序字段时用','分隔.
   */
  public String getOrderBy() {
    return orderBy;
  }
  /**
   * 设置排序字段,多个排序字段时用','分隔.
   */
  public void setOrderBy(final String orderBy) {
    this.orderBy = orderBy;
  }
  /**
   * 获得排序方向.
   */
  public String getOrder() {
    return order;
  }
  /**
   * 设置排序方式.
   *
   * @param order 可选值为desc或asc
   */
  public void setOrder(String order) {
    this.order = order;
  }
  /**
   * 查询对象时是否自动另外执行count查询获取总记录数, 默认为false.
   */
  public boolean isAutoCount() {
    return autoCount;
  }
  /**
   * 查询对象时是否自动另外执行count查询获取总记录数.
   */
  public void setAutoCount(final boolean autoCount) {
    this.autoCount = autoCount;
  }
  //-- 访问查询结果函数 --//
  /**
   * 取得页内的记录列表.
   */
  public List<T> getResult() {
    return result;
  }
  /**
   * 设置页内的记录列表.
   */
  public void setResult(final List<T> result) {
    this.result = result;
  }
  /**
   * 取得总记录数, 默认值为-1.
   */
  public long getTotalCount() {
    return totalCount;
  }
  /**
   * 设置总记录数.
   */
  public void setTotalCount(final long totalCount) {
    this.totalCount = totalCount;
  }
  /**
   * 根据pageSize与totalCount计算总页数, 默认值为-1.
   */
  public long getTotalPages() {
    if (totalCount < 0)
      return -1;
    long count = totalCount / pageSize;
    if (totalCount % pageSize > 0) {
      count++;
    }
    return count;
  }
  /**
   * 是否还有下一页.
   */
  public boolean isHasNext() {
    return (pageNo + 1 < getTotalPages());
  }
  /**
   * 取得下页的页号, 序号从0开始.
   * 当前页为尾页时仍返回尾页序号.
   */
  public int getNextPage() {
    if (isHasNext())
      return pageNo + 1;
    else
      return pageNo;
  }
  /**
   * 是否还有上一页.
   */
  public boolean isHasPre() {
    return (pageNo - 1 >= 0);
  }
  /**
   * 取得上页的页号, 序号从1开始.
   * 当前页为首页时返回首页序号.
   */
  public int getPrePage() {
    if (isHasPre())
      return pageNo - 1;
    else
      return pageNo;
  }
}

下面是封装的POJO对象,界面listview的item展示就是靠它

public class Record {
  private Integer rId;
  private String fromUser;
  private String toUser;
  private String content;
  private String rTime;
  private Integer isReaded;
  public Integer getrId() {
    return rId;
  }
  public void setrId(Integer rId) {
    this.rId = rId;
  }
  public String getFromUser() {
    return fromUser;
  }
  public void setFromUser(String fromUser) {
    this.fromUser = fromUser;
  }
  public String getToUser() {
    return toUser;
  }
  public void setToUser(String toUser) {
    this.toUser = toUser;
  }
  public String getContent() {
    return content;
  }
  public void setContent(String content) {
    this.content = content;
  }
  public String getrTime() {
    return rTime;
  }
  public void setrTime(String rTime) {
    this.rTime = rTime;
  }
  public Integer getIsReaded() {
    return isReaded;
  }
  public void setIsReaded(Integer isReaded) {
    this.isReaded = isReaded;
  }
}

好吧,来看下DAO类里的重要方法同样是Page对象,在DAO类里做的操作就是对总记录数和结果list进行赋值

public Page<Record> getRecordPage(Page<Record> page, String loginName,
      String contactName) {
    int pageSize = page.getPageSize();
    int pageNo = page.getPageNo();
    String sql = "select * from "
        + ContactsManagerDbAdapter.TABLENAME_RECORD
        + " where (fromUser = ? and toUser = ?) or (fromUser = ? and toUser = ?)"
        + " Limit " + String.valueOf(pageSize) + " Offset "
        + String.valueOf(pageNo * pageSize);
    String[] selectionArgs = { loginName, contactName, contactName,
        loginName };
    Cursor cursor = mSQLiteDatabaseWritable.rawQuery(sql, selectionArgs);
    List<Record> result = new ArrayList<Record>();
    for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
      Record record = new Record();
      record.setrId(cursor.getInt(0));
      record.setFromUser(cursor.getString(1));
      record.setToUser(cursor.getString(2));
      record.setContent(cursor.getString(3));
      record.setrTime(cursor.getString(4));
      record.setIsReaded(cursor.getInt(5));
      result.add(record);
    }
    page.setTotalCount(getRowCount(loginName, contactName));
    page.setResult(result);
    cursor.close();
    return page;
}
/**
* 总记录数
*/
public int getRowCount(String loginName, String contactName){
    String sql = "select * from "
      + ContactsManagerDbAdapter.TABLENAME_RECORD
      + " where (fromUser = ? and toUser = ?) or (fromUser = ? and toUser = ?)";
    String[] selectionArgs = { loginName, contactName, contactName,
        loginName };
    Cursor cursor = mSQLiteDatabaseWritable.rawQuery(sql, selectionArgs);
    int count = cursor.getCount();
    cursor.close();
    return count;
}

关于listview的展示和自定义适配器,在此不提起,总之界面上上一页和下一页按钮的点击事件需要刷新listview

public class ChatHistory extends Activity {
  ListView historyView;
  Button prevPageBtn;
  Button nextPageBtn;
  TextView historyPageTv;
  Button backChatsHistoryBtn;
  Button deleteHistoryBtn;
  List<Record> historyRecordList;
  Page<Record> page;
  String loginName;
  String contactName;
  ChatHistoryService chatHistoryService;
  ContactsManagerDbAdapter dbAdapter;
  private BaseAdapter adapter;
  private static final int STATUS_CHANGE = 0;
  private Handler mHandler;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.chats_history);
    historyView = (ListView) findViewById(android.R.id.list);
    prevPageBtn = (Button) findViewById(R.id.chat_prev_page);
    nextPageBtn = (Button) findViewById(R.id.chat_next_page);
    historyPageTv = (TextView) findViewById(R.id.history_page);
    backChatsHistoryBtn = (Button) findViewById(R.id.back_chats_history);
    deleteHistoryBtn = (Button) findViewById(R.id.delete_history);
    SharedPreferences sharedata = ChatHistory.this.getSharedPreferences("data", 0);
    loginName = sharedata.getString("loginName", "");
    contactName = getIntent().getStringExtra("contactName");
    dbAdapter = new ContactsManagerDbAdapter(getApplicationContext());
    dbAdapter.open();
    chatHistoryService = new ChatHistoryService(ChatHistory.this);
    page = new Page<Record>();
    page.setPageSize(8);
    page = chatHistoryService.getHistoryPage(page, loginName, contactName, dbAdapter);
    historyRecordList = page.getResult();
    updateTextView();
    prevPageBtn.setOnClickListener(prevPageButtonListener);
    nextPageBtn.setOnClickListener(nextPageButtonListener);
    backChatsHistoryBtn.setOnClickListener(backButtonListener);
    deleteHistoryBtn.setOnClickListener(deleteHistoryButtonListener);
    adapter = new HistoryListAdapter(ChatHistory.this);
    historyView.setAdapter(adapter);
    mHandler = new Handler(){
       public void handleMessage(Message msg) {
          switch(msg.what){
          case STATUS_CHANGE:
            // 处理UI更新等操作
            updateUI();
          }
       };
    };
  }
  private void updateUI() {
    //详细的更新
    adapter.notifyDataSetChanged();// 更新ListView
    updateTextView();
  }
  /**
   * 更新页码
   */
  private void updateTextView(){
    if(historyRecordList.size() == 0){
      historyPageTv.setText(0 + "/" + 0);
    } else{
      historyPageTv.setText(page.getPageNo() + 1 + "/" + page.getTotalPages());
    }
  }
  public class HistoryListAdapter extends BaseAdapter{
    private class RecentViewHolder {
      TextView sender_context;
      TextView rTime;
    }
    Context context;
    LayoutInflater mInflater;
    public HistoryListAdapter(Context context){
      this.context = context;
      mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    @Override
    public int getCount() {
      // TODO Auto-generated method stub
      return historyRecordList.size();
    }
    @Override
    public Object getItem(int position) {
      // TODO Auto-generated method stub
      return historyRecordList.get(position);
    }
    @Override
    public long getItemId(int position) {
      // TODO Auto-generated method stub
      return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      // TODO Auto-generated method stub
      RecentViewHolder holder;
      if (convertView == null) {
        convertView = mInflater.inflate(R.layout.message_layout, null);
        holder = new RecentViewHolder();
        holder.sender_context = (TextView) convertView
            .findViewById(R.id.message_view_sender_content);
        holder.rTime = (TextView) convertView
            .findViewById(R.id.message_view_timestamp);
        convertView.setTag(holder);
      } else {
        holder = (RecentViewHolder) convertView.getTag();
      }
      Record record = historyRecordList.get(position);
      if (record != null) {
        holder.sender_context.setText(record.getFromUser() + ":" + record.getContent());
        holder.rTime.setText(record.getrTime());
      }
      return convertView;
    }
  }
  /**
   * 上一页按钮的监听事件
   */
  OnClickListener prevPageButtonListener = new OnClickListener(){
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
      if(page.isHasPre()){
        page.setPageNo(page.getPageNo() - 1);
        historyRecordList = chatHistoryService.getHistoryPage(page, loginName, contactName, dbAdapter).getResult();
        Message msg = new Message();
        msg.what = STATUS_CHANGE;
        mHandler.sendMessage(msg);// 向Handler发送消息,更新UI
      }
    }
  };
  /**
   * 下一页按钮的监听事件
   */
  OnClickListener nextPageButtonListener = new OnClickListener(){
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
      if(page.isHasNext()){
        page.setPageNo(page.getPageNo() + 1);
        historyRecordList = chatHistoryService.getHistoryPage(page, loginName, contactName, dbAdapter).getResult();
        Message msg = new Message();
        msg.what = STATUS_CHANGE;
        mHandler.sendMessage(msg);// 向Handler发送消息,更新UI
      }
    }
  };
  /**
   * 删除历史记录按钮监听器
   */
  OnClickListener deleteHistoryButtonListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
    }
  };
  /** 退出聊天界面监听器 */
  OnClickListener backButtonListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
      // 返回到聊天界面
      finish();
      dbAdapter.close();
    }
  };
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    // 按下键盘上返回按钮
    if (keyCode == KeyEvent.KEYCODE_BACK) {
      finish();
      dbAdapter.close();
      return true;
    } else {
      return super.onKeyDown(keyCode, event);
    }
  }
}

上一页,下一页所做的操作也就是在判断是否有上一页和下一页的情况下对页号pageNo的加减操作
最后写上ChatHistoryService.java总觉得是多余的

public class ChatHistoryService {
  Context context;
  public ChatHistoryService(Context context) {
    this.context = context;
  }
  public Page<Record> getHistoryPage(Page<Record> page, String loginName,
      String contactName, ContactsManagerDbAdapter dbAdapter) {
    RecordDao recordDao = new RecordDao(dbAdapter);
    return recordDao.getRecordPage(page, loginName, contactName);
  }
  public int deleteHistory(String loginName,
      String contactName, ContactsManagerDbAdapter dbAdapter){
    RecordDao recordDao = new RecordDao(dbAdapter);
    return recordDao.deleteHistoryRecord(loginName, contactName);
  }
}

顺带放上XML布局文件吧
chats_history.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 与好友聊天窗口.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:background="@color/white">
  <ListView android:id="@android:id/list" android:layout_width="fill_parent"
    android:layout_height="200dip" android:layout_weight="1"
    android:transcriptMode="normal" android:fadingEdge="none"
    android:padding="4px" android:fastScrollEnabled="true"
    android:smoothScrollbar="false"
    android:focusable="true" android:dividerHeight="0dip"
    android:cacheColorHint="#00000000" android:divider="@drawable/divider" />
  <!-- 引用聊天内容.xml -->
  <LinearLayout android:layout_width="fill_parent"
    android:layout_height="50.0dip" android:orientation="horizontal"
    android:background="#ccc" android:paddingLeft="3dip"
    android:paddingTop="3dip">
    <Button android:id="@+id/chat_prev_page"
      android:layout_width="wrap_content" android:layout_height="wrap_content"
      android:background="@drawable/chat_prev_page" />
    <TextView android:id="@+id/history_page" android:layout_width="30.0dip"
      android:layout_height="25.0dip" android:gravity="center"
      android:text="1/1"/>
    <Button android:id="@+id/chat_next_page" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:background="@drawable/chat_next_page" />
    <Button android:id="@+id/delete_history" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:background="@drawable/delete_history_button" />
    <Button android:id="@+id/export_history" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:background="@drawable/export_history_button" />
    <Button android:id="@+id/back_chats_history"
      android:layout_width="wrap_content" android:layout_height="wrap_content"
      android:background="@drawable/back_btn"/>
  </LinearLayout>
</LinearLayout>

message_layout.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 消息内容的展示 -->
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 >
 <!-- android:background="@drawable/item_style" -->
  <TextView android:id="@+id/message_view_sender_content"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:autoLink="all" />
  <TextView android:id="@+id/message_view_timestamp"
    android:layout_alignParentRight="true" android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:layout_below="@+id/message_view_message"
    android:layout_gravity="right" />
</LinearLayout>

最后来看看效果吧,别欺负我没贴上数据库建表语句,看下我的POJO类就知道我数据库表怎么建的

希望本文所述对大家的Android程序设计有所帮助。

(0)

相关推荐

  • Android开发中滑动分页功能实例详解

    本文实例讲述了Android开发中滑动分页功能.分享给大家供大家参考,具体如下: android UI 往右滑动,滑动到最后一页就自动加载数据并显示 如图: Java代码: package cn.anycall.ju; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import andro

  • Android中实现多行、水平滚动的分页的Gridview实例源码

    功能要求: (1)比如每页显示2X2,总共2XN,每个item显示图片+文字(点击有链接). 如果单行水平滚动,可以用Horizontalscrollview实现. 如果是多行水平滚动,则结合Gridview(一般是垂直滚动的)和Horizontalscrollview实现. (2)水平滚动翻页,下面有显示当前页的icon. 1.实现自定义的HorizontalScrollView(HorizontalScrollView.java): 因为要翻页时需要传当前页给调用者,所以fling函数中自己

  • Android滑动动态分页实现方法

    本文实例讲述了Android滑动动态分页实现方法.分享给大家供大家参考,具体如下: 实现 Android.widget.AbsListView.OnScrollListener 主要代码: private int lastItemIndex; @Override public void onScroll(AbsListView v, int firstVisibleItem,int visibleItemCount, int totalItemCount) { lastItemIndex = f

  • Android ListView分页功能实现方法

    通过本次小Demo我学到了: 1.ListView的小小的一个分页功能 2.加深了对自定义控件的理解 3.对ListView的优化 4.对BaseAdapter的使用 5.自定义Adapter 6.接口的回调 要实现下面的效果--当拖动ListView到底部的时候,显示一个ProgressBar和一个"正在加载..."的TextView.并且过两秒钟后,在下面加载出新的数据.项目的目录结构和程序要实现的效果如下:   首先是布局部分: 我为了实现此效果,首先在布局文件中新建了一个foo

  • Android提高之SQLite分页读取实现方法

    一般来说,Android自身就包含了常用于嵌入式系统的SQLite,这样就免去了开发者自己移植安装的功夫.SQLite 支持多数SQL92标准,很多常用的SQL命令都能在SQLite上面使用,除此之外Android还提供了一系列自定义的方法去简化对SQLite数据库的操作.不过有跨平台需求的程序还是建议使用标准的SQL语句,毕竟这样容易在多个平台之间进行移植. 先来贴出本文程序运行的结果图: 本文实例程序主要讲解了SQLite的基本用法,如:创建数据库,使用SQL命令查询数据表.插入数据,关闭数

  • Android实现ListView分页自动加载数据的方法

    Android应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验.因此,很多应用都是采用分批次加载的形式来获取用户所需的数据.例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据. 下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListVie

  • Android App中使用ViewPager实现滑动分页的要点解析

    以前如果要做 Tab 分页的话,必须要用一个很难用的 TabActivity,而且做出来的效果很差,弹性也很小 忘了从什么时候开始,Google release 了 ViewPager 这好东西取代了以前难用的 Gallery 元件,加上从 Honeycomb 导入的 Fragment 之后终于能够简单做出好看又好用的 Layout 了! 这里我们采用PagerTabStrip ,做出来的效果如下 特色就是使用简单,出来的效果则是目前显示的分页 Tab 的文字会自动置中,然后分别在左右显示上一个

  • Android实现简单的分页效果

    本文实例为大家分享了Android分页效果的具体代码,供大家参考,具体内容如下 1.实现分页最主要的就是封装分页代码,然后在按钮里实现相关的操作 /** * 分页工具 * * @Project App_Page * @Package com.android.dividepage * @author chenlin * @version 1.0 * @Date 2012年6月2日 * @Note TODO * @param <T> */ public class PageHelper<T&

  • Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多

    最近做的类似于微博的项目中,有个Android功能要使用到listview的向下拉刷新来刷新最新消息,向上拉刷新(滑动分页)来加载更多. 新浪微博就是使用这种方式的典型. 当用户从网络上读取微博的时候,如果一下子全部加载用户未读的微博这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了,其实这个分页可以做成客户端的分页,也可以做成服务器端的分页(点击加载时,从服务器对应的加载第N页就好了!!!).通过分

  • Android实现基于滑动的SQLite数据分页加载技术(附demo源码下载)

    本文实例讲述了Android实现基于滑动的SQLite数据分页加载技术.分享给大家供大家参考,具体如下: main.xml如下: <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_settings" android:orderInCategory="100" android:showAs

  • Android之ListView分页加载数据功能实现代码

    什么是ListView分页加载数据功能呢?在现在的大数据时代,我们不可能把某些数据全部展示到界面,好比我们经常会看的QQ空间一样,当你看动态的时候,系统不可能会把所有好友的动态都展示在上面,你能看到的一般都是最新好友更新的动态,假如你要看非最新的好友动态,通常你都会手指向上滑动屏幕然后去查看,当界面下滑到一定数量的时候,就会看到一个"查看更多",然后突然停顿一下,系统会通过网络去给你刷新其他动态信息,这样的功能我们一般叫做数据下拉刷新功能,也就是我们的分页加载功能,具体的实现是怎样的呢

随机推荐