一、资源
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数据的改变。