转载请注明出处,谢谢http://blog.csdn.net/harryweasley/article/details/51007348

始终觉得讲ui效果要先放上效果图,要不让其他人好不容易看完了,发现并不是他想要的效果,那岂不是坑了苦逼的程序员,程序员何苦为难程序员。效果图如下所示:

此应用,是viewPager结合fragment,fragment里又是一个gridView来实现的,实现向右滑动,分页加载数据的功能

文章末尾,有该应用的下载资源。

先说下该应用的功能吧,打开该应用,初始加载两个页面,第0页和第1页,当到达最后一页的时候,就会加载后一页的数据,如此一直加载下去。每个页面是一个gridView,Activity和fragment进行数据的传递。

项目的java目录如下所示:

你可能会想,这样一直加载页面出来,会不会造成oom,答案是不会。因为FragmentPagerAdapter只会保留当前页面,前一个页面和后一个页面的实例到内存,其他的都将删除。

关于Activity和fragment数据传递,因为我想要传递对象,所以我用到了bundle.putParcelableArrayList(“”,”“);这个方法,关于这个方法更多的介绍,可以查看http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html

所以我的arrayList里传递的类实现了Parcelable接口,如下所示:

package com.example.viewpagerdemo;import android.os.Parcel;
import android.os.Parcelable;public class Model implements Parcelable {private String index;private String name;public Model(String index, String name) {this.index = index;this.name = name;}// 重写describeContents方法,内容接口描述,默认返回0就可以,基本不用@Overridepublic int describeContents() {return 0;}// 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从// Parcel容器获取数据@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(index);dest.writeString(name);}/*** 其中public static* final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel* (Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size)* 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。*/public static final Parcelable.Creator<Model> CREATOR = new Parcelable.Creator<Model>() {@Overridepublic Model createFromParcel(Parcel source) {return new Model(source.readString(), source.readString());}@Overridepublic Model[] newArray(int size) {return new Model[size];}};public String getIndex() {return index;}public void setIndex(String index) {this.index = index;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

里面已经写了注释,这里就不用再解释更多了。

MainActivity的内容,如下所示:

package com.example.viewpagerdemo;import java.util.ArrayList;
import java.util.List;import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;public class MainActivity extends FragmentActivity {private ViewPager vp;private List<Fragment> fragments;private SimplePageAdapter pageAdapter;/*** 传递的数据*/private ArrayList<Model> modelList;/*** 一共有多少页*/private int pageCount;private int totalCount = 18;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);vp = (ViewPager) findViewById(R.id.viewpager);fragments = new ArrayList<Fragment>();initDatas();int size = modelList.size();if (size % 9 == 0) {pageCount = size / 9;} else {pageCount = size / 9 + 1;}for (int i = 0; i < pageCount; i++) {//初始化每一个fragmentGridFragment gf = GridFragment.newInstance(i, modelList);fragments.add(gf);}//初始化pageAdapterpageAdapter = new SimplePageAdapter(getSupportFragmentManager(),fragments);vp.setAdapter(pageAdapter);vp.addOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int arg0) {if (arg0 == pageCount - 1) {// 在最后一页,开始加载后一页的数据for (int i = totalCount; i < totalCount + 9; i++) {Model model = new Model(i + "", i + "name");modelList.add(model);}totalCount += 9;pageAdapter.addFragment(pageCount++, modelList);pageAdapter.notifyDataSetChanged();}}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {}});}/*** 初始化数据,刚开始有18个*/private void initDatas() {modelList = new ArrayList<Model>();for (int i = 0; i < totalCount; i++) {Model model = new Model(i + "", i + "name");modelList.add(model);}}}

37行到41行,是确定刚开始,有几个页面。
44行是初始化GridFragment,在这里,将数据通过bundle进行了传递。
50行进行了初始化pageAdapter,同时在66行,有调用addFragment这个方法。接下来看下SimplePageAdapter里面都写了什么。

下面是SimplePageAdapter里面的内容:

package com.example.viewpagerdemo;import java.util.ArrayList;
import java.util.List;import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;public class SimplePageAdapter extends FragmentStatePagerAdapter {private List<Fragment> fragments;public SimplePageAdapter(FragmentManager fm, List<Fragment> fragments) {super(fm);this.fragments = fragments;}@Overridepublic Fragment getItem(int arg0) {return fragments.get(arg0);}@Overridepublic int getCount() {return fragments.size();}public void addFragment(int i,ArrayList<Model> modelList){GridFragment  gf=GridFragment.newInstance(i,modelList);fragments.add(gf);}}

第29行是增加新的fragment,即增加新的页面。

最后看下GridFragment里面的内容。

package com.example.viewpagerdemo;import java.util.ArrayList;
import java.util.List;import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;public class GridFragment extends Fragment {private View view;private GridView gv;private int index = -1;private FragmentActivity context;private List<Model> modelList;private TextView no;public static GridFragment newInstance(int index, ArrayList<Model> modelList) {GridFragment gf = new GridFragment();Bundle bundle = new Bundle();bundle.putInt("index", index);bundle.putParcelableArrayList("model", modelList);gf.setArguments(bundle);return gf;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {if (view == null) {//防止重复加载布局context = getActivity();Bundle bundle = getArguments();index = bundle.getInt("index");modelList = bundle.getParcelableArrayList("model");List<Model> newModels;int last = 9 * index + 9;if (last >= modelList.size()) {newModels = modelList.subList((9 * index), (modelList.size()));} else {newModels = modelList.subList((9 * index), (last));}Log.i("tag", "当前页数是" + index + "view是null哦");view = LayoutInflater.from(context).inflate(R.layout.fragment_grid,container, false);gv = (GridView) view.findViewById(R.id.gridview);no = (TextView) view.findViewById(R.id.no);no.setText("这个是第" + (index + 1) + "页");// 这里重新开辟一个地址空间,来保存list,否则会报ConcurrentModificationException错误final ArrayList<Model> text = new ArrayList<Model>();text.addAll(newModels);gv.setAdapter(new GridBaseAdapter(getActivity(), text));gv.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {Toast.makeText(context,"点击的item是" + text.get(position).getIndex(),Toast.LENGTH_SHORT).show();}});} else {Log.i("tag", "当前页数是" + index + "view不不不是null哦");ViewGroup root = (ViewGroup) view.getParent();if (root != null) {root.removeView(view);}}Log.i("tag", "当前页数是" + index);return view;}}

关于第49行到第56行,这里进行一些解释:Activity和fragment之间的数据传递,我是将所有页面的list全部保存在内存中,所以这里会根据index来确定每个页面的数据内容。

第46行的那个注释,和他下面的内容,是我目前解决ConcurrentModificationException的方法。

我想你可能对第41行的判断,81行到87行的内容有疑惑,你可以看这篇文章,http://blog.csdn.net/harryweasley/article/details/50999802

之后就是GridBaseAdapter里的内容了,这个很简单,没有很多复杂的功能,我直接贴出来,就不解释了。

package com.example.viewpagerdemo;import java.util.List;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;public class GridBaseAdapter extends BaseAdapter {private List<Model> modelList;private Context context;public GridBaseAdapter(Context context, List<Model> modelList) {this.modelList = modelList;this.context = context;}@Overridepublic int getCount() {return modelList.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {holder = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item_grid, parent, false);holder.tv = (TextView) convertView.findViewById(R.id.textview);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.tv.setText(modelList.get(position).getIndex());return convertView;}static class ViewHolder {TextView tv;}
}

其他的xml布局,我这里就不粘贴了,你可以直接下载源码查看。

参考文章:

如何更新及替换ViewPager中的Fragment,这篇文章将FragmentPagerAdapter和FragmentStatePagerAdapter的区别讲解的非常好,推荐大家去看:https://segmentfault.com/a/1190000003742057

fragment的陷阱,这篇文章说了,fragment为什么使用if (view == null) {}判断
http://blog.csdn.net/harryweasley/article/details/50999802

源码下载:
http://download.csdn.net/detail/harryweasley/9479123

Android GridView横向滚动,分页加载数据相关推荐

  1. listView分批和分页加载数据

    在Android应用程序中,有时候会向listView中加载很多数据,向listView中加载数据是一个耗时的过程,加载过多的数据用户停留在listView上,一直等待,给用户的体验特别不好,比如向服 ...

  2. List 分页加载数据控制机制

    分页加载是一种应用很广泛的数据展示控制机制,相信绝大多数开发者对于这一套机制都非常熟悉.这篇文章的主要目的结合实际的使用场景,对以往在开发中遇到一些概念进行梳理,归纳的同时加深理解,也希望能帮助更多刚 ...

  3. 微信小程序数据拼接_最佳方式实现微信小程序分页加载数据

    一般小程序做分页加载数据,会做一些下拉加载更多.然后上拉刷新的操作.数据放在一个for循环里去加载,数据源是一个数组对象.在加载下一页数据时,将下一页的数据拼到当前数组后面.这样的确可以实现分页加载数 ...

  4. 分组显示的ListView分页加载数据

    参考:  http://www.cnblogs.com/qianxudetianxia/archive/2011/06/07/2074326.html 分组的ListView的拖拽  http://w ...

  5. Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果)...

    Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果) 首句依然是那句老话,你懂得! finddreams :(http://blog.csdn.net/finddr ...

  6. 小程序下滑分页加载数据

    小程序下滑分页加载数据 1. 在data定义page参数 params: {pageNum: 1,pageSize: 10,total: 0,searchValue: ''}, 2. 请求接口数据 g ...

  7. 微信小程序 实现分页加载数据

    实现分页加载数据要用到页面加载触底事件 onReachBottom: function () { } 首先在 js 定义初始数据 data: { //用来接收后端数据list:[], //当前页cur ...

  8. Android中ListView分页加载数据

    熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组件,我们今天就要讲一讲列表组件ListView加载数据的相关内容 ...

  9. 微信小程序实现上拉分页加载数据

    文章目录 1. 实现上拉请求 2. 实现分页加载 3. 数据全部加载完成后阻止上拉刷新 4. 容易发送上拉刷新失败问题 微信小程序的上拉和下拉刷新是比较常见的功能,下拉刷新比较容易实现,这里说一下上拉 ...

最新文章

  1. 设置elf文件链接库的路径
  2. python的self
  3. c#读蓝牙数据_CSharp--BlueTooth 实现蓝牙通讯的程序 C#开发 可以发送和接收数据 方便二次开发 - 下载 - 搜珍网...
  4. CentOS6.4之Linux软件包管理
  5. python 赋值操作的知识点
  6. IIS7.X上传文件大小受限制解决方法
  7. 第5章 set命令详解
  8. UPNP解读2-含netbios,wins,DNS
  9. Android之内容提供者ContentProvider的总结
  10. 《洛克菲勒留给儿子的38封信》
  11. Nginx配置浏览器缓存
  12. 基于Gevent的firefly重要迭代版本推出
  13. 一个简单的文本聚类实现(python)
  14. 对于给定的正整数N,需要计算 S=1!+2!+3!+...+N!
  15. 马拦过河卒(三种做法)
  16. springboot系列(十四):如何实现发送图片、doc文档等附件邮件?你一定得会|超级详细,建议收藏
  17. 无人驾驶量产的曙光究竟在哪里?参与直播,易航智能CEO为你解码“渐进式”路径 | 量子位·视点...
  18. 服务器端文件包含,服务器端包含、嵌入技术SSI(Server SideInc lude)详解
  19. 基于 Android 平台的手机订餐系统的设计与实现
  20. 广州移动、中国信通院广州分院携手宝能汽车打造5G车联网

热门文章

  1. RRT*算法的原理简介以及Python实现代码
  2. 五一公众号文章就用来逗编辑器编辑排版
  3. 硬链接和软连接的区别
  4. vue项目中:PC端导出csv或excel数据表方法及其移动端导出表格方法
  5. html制作在线播放,如何使用Jquery制作简单的HTML播放列表
  6. 寺库发布2019年第一季度财报,奢侈品电商还将增长多久?
  7. html中图片一角的卷起效果,一个书页卷角的HTMLCSS效果
  8. Keil、uVision、RealView、MDK、Keil C51之间的区别比较
  9. 5.5 漏洞扫描:Web安全漏洞扫描及审计
  10. 从股市狂跌谈集体无意识