Android GridView横向滚动,分页加载数据
转载请注明出处,谢谢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横向滚动,分页加载数据相关推荐
- listView分批和分页加载数据
在Android应用程序中,有时候会向listView中加载很多数据,向listView中加载数据是一个耗时的过程,加载过多的数据用户停留在listView上,一直等待,给用户的体验特别不好,比如向服 ...
- List 分页加载数据控制机制
分页加载是一种应用很广泛的数据展示控制机制,相信绝大多数开发者对于这一套机制都非常熟悉.这篇文章的主要目的结合实际的使用场景,对以往在开发中遇到一些概念进行梳理,归纳的同时加深理解,也希望能帮助更多刚 ...
- 微信小程序数据拼接_最佳方式实现微信小程序分页加载数据
一般小程序做分页加载数据,会做一些下拉加载更多.然后上拉刷新的操作.数据放在一个for循环里去加载,数据源是一个数组对象.在加载下一页数据时,将下一页的数据拼到当前数组后面.这样的确可以实现分页加载数 ...
- 分组显示的ListView分页加载数据
参考: http://www.cnblogs.com/qianxudetianxia/archive/2011/06/07/2074326.html 分组的ListView的拖拽 http://w ...
- Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果)...
Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果) 首句依然是那句老话,你懂得! finddreams :(http://blog.csdn.net/finddr ...
- 小程序下滑分页加载数据
小程序下滑分页加载数据 1. 在data定义page参数 params: {pageNum: 1,pageSize: 10,total: 0,searchValue: ''}, 2. 请求接口数据 g ...
- 微信小程序 实现分页加载数据
实现分页加载数据要用到页面加载触底事件 onReachBottom: function () { } 首先在 js 定义初始数据 data: { //用来接收后端数据list:[], //当前页cur ...
- Android中ListView分页加载数据
熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组件,我们今天就要讲一讲列表组件ListView加载数据的相关内容 ...
- 微信小程序实现上拉分页加载数据
文章目录 1. 实现上拉请求 2. 实现分页加载 3. 数据全部加载完成后阻止上拉刷新 4. 容易发送上拉刷新失败问题 微信小程序的上拉和下拉刷新是比较常见的功能,下拉刷新比较容易实现,这里说一下上拉 ...
最新文章
- 设置elf文件链接库的路径
- python的self
- c#读蓝牙数据_CSharp--BlueTooth 实现蓝牙通讯的程序 C#开发 可以发送和接收数据 方便二次开发 - 下载 - 搜珍网...
- CentOS6.4之Linux软件包管理
- python 赋值操作的知识点
- IIS7.X上传文件大小受限制解决方法
- 第5章 set命令详解
- UPNP解读2-含netbios,wins,DNS
- Android之内容提供者ContentProvider的总结
- 《洛克菲勒留给儿子的38封信》
- Nginx配置浏览器缓存
- 基于Gevent的firefly重要迭代版本推出
- 一个简单的文本聚类实现(python)
- 对于给定的正整数N,需要计算 S=1!+2!+3!+...+N!
- 马拦过河卒(三种做法)
- springboot系列(十四):如何实现发送图片、doc文档等附件邮件?你一定得会|超级详细,建议收藏
- 无人驾驶量产的曙光究竟在哪里?参与直播,易航智能CEO为你解码“渐进式”路径 | 量子位·视点...
- 服务器端文件包含,服务器端包含、嵌入技术SSI(Server SideInc lude)详解
- 基于 Android 平台的手机订餐系统的设计与实现
- 广州移动、中国信通院广州分院携手宝能汽车打造5G车联网