zoukankan      html  css  js  c++  java
  • 【Android学习笔记】GridView+ResourceCursorAdapter 分页实现

    一、资源

           GridView实现的分页,这篇博文写得简单,但是下源码就一目了然

            http://daimajishu.iteye.com/blog/1086643

    二、效果图

       第一页:

    第二页:

    滑动中:

    蛋疼啊ResourceCursorAdapter .....

    三、核心分析

        之前的GridView Footer实现和分页是一起做的,所以,getView,newView,bindView机制也了解了

       看资源给的例子,核心代码在:

        原理一:计算数据总量,之后每个页面新建gridView,新建的GridView作为子View,加载在ScrollView中进行滑动显示。

    View Code
     1    // get all apps 
    2 final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
    3
    4 // the total pages
    5 final int PageCount = (int)Math.ceil(apps.size()/APP_PAGE_SIZE);
    6 Log.e(TAG, "size:"+apps.size()+" page:"+PageCount);
    7 for (int i=0; i<PageCount; i++) {
    8 GridView appPage = new GridView(this);
    9 // get the "i" page data
    10 appPage.setAdapter(new AppAdapter(this, apps, i));
    11
    12 appPage.setNumColumns(4);
    13 appPage.setOnItemClickListener(listener);
    14 mScrollLayout.addView(appPage);
    15 }

     原理二:核心:  每个页面加载的数据分割,根据所在页数以及每页呈现的数据上限提取出此页面的数据

    View Code
     1 public AppAdapter(Context context, List<ResolveInfo> list, int page) {
    2 mContext = context;
    3 pm = context.getPackageManager();
    4
    5 mList = new ArrayList<ResolveInfo>();
    6 int i = page * APP_PAGE_SIZE;
    7 int iEnd = i+APP_PAGE_SIZE;
    8 while ((i<list.size()) && (i<iEnd)) {
    9 mList.add(list.get(i));
    10 i++;
    11 }
    12 }

      不过,对于原作的这部分,我认为又耗控件又耗时间,他那个判断语句我是有点没明白也没多想,还有就是每次获取数据都得新建一个list,然后不断的copy,这里觉得有点不值

          所以这些地方我稍作了改动,原理还是一样的,只是灭掉了他的copy操作。

              即:通过重写getCount() 来控制此页面gridView的信息加载量

     1 public int getCount() {
    2
    3 //判断当前页面,控制返回的数据量,实现分页
    4 int i = page * PAGE_BOARD_SIZE;
    5 int iEnd = i+PAGE_BOARD_SIZE;
    6 int size=mCursor.getCount();
    7 if(size>i&&size<iEnd)
    8 return (size-i);
    9 else
    10 return PAGE_BOARD_SIZE;
    11
    12
    13 }
    14

      

      原理三:对直接BaseAdapter,实现分页的话只要在getView()里数据填充的时候,根据当前的page,页面的数据规格PAGE_BOARD_SIZE,当前view的postion来定位数据即可

         虽然我一直觉得ResourceCursorAdapter很蛋疼 ,但是搞清了getView,newView,bindView调用机制,这里处理也就方便起来

                 总的adapter代码出来就差不多这样,数据的定位一定要注意

    View Code
     1 /* (non-Javadoc)
    2 * @see android.widget.CursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
    3 */
    4 @Override
    5 public void bindView(View view, Context context, Cursor cursor) {
    6 // TODO Auto-generated method stub
    7 final ViewHolder cache = (ViewHolder) view.getTag();
    8
    9 cache.tx_boardname.setText(cursor.getString(index[1]));
    10 cache.tx_boardnumber.setText(cursor.getString(index[2]));
    11
    12
    13 }
    14
    15 /* (non-Javadoc)
    16 * @see android.widget.ResourceCursorAdapter#newView(android.content.Context, android.database.Cursor, android.view.ViewGroup)
    17 */
    18 @Override
    19 public View newView(Context context, Cursor cursor, ViewGroup parent) {
    20 // TODO Auto-generated method stub
    21 View view = super.newView(context, cursor, parent);
    22 ViewHolder holder = new ViewHolder();
    23 holder.tx_boardname=(TextView) view.findViewById(R.id.tv_boardname);
    24 holder.tx_boardnumber=(TextView) view.findViewById(R.id.tv_boardnumber);
    25 view.setTag(holder);
    26 return view;
    27 }
    28
    29 private class ViewHolder{
    30
    31 private TextView tx_boardname;
    32 private TextView tx_boardnumber;
    33 }
    34
    35 public int getCount() {
    36
    37 //判断当前页面,控制返回的数据量,实现分页
    38 int i = page * PAGE_BOARD_SIZE;
    39 int iEnd = i+PAGE_BOARD_SIZE;
    40 int size=mCursor.getCount();
    41 if(size>i&&size<iEnd)
    42 return (size-i);
    43 else
    44 return PAGE_BOARD_SIZE;
    45
    46
    47 }
    48
    49
    50 public View getView(int position, View convertView, ViewGroup parent) {
    51
    52
    53 if(mCursor==null){
    54 throw new IllegalStateException("this should only be called when the cursor is valid");
    55 }
    56
    57 //控制Cursor的移动
    58 if (!mCursor.moveToPosition(page*PAGE_BOARD_SIZE+position)) {
    59
    60 throw new IllegalStateException("couldn't move cursor to position " + (page*PAGE_BOARD_SIZE+position));
    61 }
    62 View v;
    63 if (convertView == null) {
    64 v = newView(mContext, mCursor, parent);
    65 } else {
    66 v = convertView;
    67 }
    68 bindView(v, mContext, mCursor);
    69 return v;
    70 }
    71

      

     记录完毕,CursorAdapter一直觉得很蛋疼的东西,都没怎么用过,结果做小项目的时候才知道它真正跟别的一些adapter的区别

      源码在这里,顺便记录:

      

    View Code
     1  protected void init(Context context, Cursor c, boolean autoRequery) {
    2 boolean cursorPresent = c != null;
    3 mAutoRequery = autoRequery;
    4 mCursor = c;
    5 mDataValid = cursorPresent;
    6 mContext = context;
    7 mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
    8 mChangeObserver = new ChangeObserver();
    9 if (cursorPresent) {
    10 c.registerContentObserver(mChangeObserver);
    11 c.registerDataSetObserver(mDataSetObserver);
    12 }
    13 }

      监听Cursor数据的改变。


  • 相关阅读:
    WinRAR的命令行模式用法介绍
    Linux find命令的用法实践
    Linux服务器磁盘扩展和oracle表空间文件迁移操作记录
    博客园开篇,自己开发的双色球小助手
    解决MySQL安装3306端口占用问题
    html书写行内元素时-tab和换行会在行内元素间引入间距
    FileReader生成图片dataurl的分析
    mysql启动流程
    npm--debug模块
    js之Symbol类型
  • 原文地址:https://www.cnblogs.com/hundan/p/2155575.html
Copyright © 2011-2022 走看看