GridView+ResourceCursorAdapter 分页实现
一、资源
GridView实现的分页,这篇博文写得简单,但是下源码就一目了然
http://daimajishu.iteye.com/blog/1086643
二、效果图
第一页:
第二页:
滑动中:
蛋疼啊ResourceCursorAdapter .....
三、核心分析
之前的GridView Footer实现和分页是一起做的,所以,getView,newView,bindView机制也了解了
看资源给的例子,核心代码在:
原理一:计算数据总量,之后每个页面新建gridView,新建的GridView作为子View,加载在ScrollView中进行滑动显示。
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 }
原理二:核心: 每个页面加载的数据分割,根据所在页数以及每页呈现的数据上限提取出此页面的数据
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代码出来就差不多这样,数据的定位一定要注意:
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的区别
源码在这里,顺便记录:
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数据的改变。