先看美团的效果:
再看我们山寨的效果:
最初我是使用VIewPager+RecyclerVIew实现的,发现在左右滑动的时候,有问题,经常滑动不了,应该是RecyclerVIew消费了Touch事件,所以弃用这个方法了(效果图是下面的效果,为了区别VIew页面,每个Page背景色不同),
后来我尝试使用ViewPager+GridView实现的,看起来一切正常,就没有再解决VIewPager+RecyclerVIew滑动冲突的问题,不过我初步分析可以用过重写ViewPager的onInterceptTouchEvent方法,判断如果是左右滑动事件就拦截事件的分发不再传递给子View(RecyclerVIew)。
如下是利用VIewPager+GridView方法实现,并塞入ListView中当做HeaderView,可以正常使用,如图:
第一个界面是自己重写的ListVIew实现的下拉刷新,第二界面使用SwipeRefreshLayout这个控件套的ListVIew实现的下拉刷新。
====================================================优雅分割线=================================================
【思路】:
之所以使用GridView作为每个ViewPager的页面,是考虑到,当这些分类条目的数据集变化时,比较好动态的更新。(通过SDK工具查看美团的View层级,发现其也是使用ViewPager里放入两个GridView实现。)
假设(模拟)数据有20条,即20个类目,先考虑一下每个GridView页面有几条几列,这里我们暂定为每页8条4列分类,则ViewPager一共有 20条/8条每页 =2.5 ,取整为3页。
这里有个疑点就是,“怎么将GridView和ViewPager合并,并在ViewPager翻页时这个GridView能正确显示数据?”,这里打了个引号“”,代表这个说法有问题,其实并不是将两个控件合并,ViewPager这里没有特殊处理,只是将GridView作为View传给ViewPager的Adapter,如刚才计算如果一共三页,则会inflate出三个GridView作为每页的VIew加入集合中,并将这个集合作为ViewPager的数据源传给ViewPager的Adapter。 这是回答如何将GridView和VIewPager合并产生关系,
那么如何在ViewPager翻页时那个GridView显示正确的数据呢?一开始我的想法是监听ViewPager的翻页事件,然后再修改GridView的数据集,然后再更新视图。。。。。
这个想法是错误的,
正确做法如下四步:这里需要将GridView的Adapter处理一下,给Adapter传入的数据集mDatas就是条目的总数据集,不用修改。
一:增加两个属性,index和pageSize,代表页数和每一页显示的最大条目上限。在给这三页的GridView设置Adapter时,传入当前页数index,然后经过计算得出正确的count和应该显示的View的数据。
二:修改getCount()方法,
@Override public int getCount() { return mDatas.size() > (mIndex + 1) * mPageSize ? mPageSize : (mDatas.size() - mIndex * mPageSize); }
先判断数据集的大小是否足够显示满本页?mDatas.size() > (mIndex+1)*mPageSize,如果够,则直接返回每一页显示的最大条目个数mPageSize,如果不够,则有几项返回几,
(mDatas.size() - mIndex * mPageSize);
三:修改getView()方法:
在给View绑定显示的数据时,根据当前下标index,和每页显示最大的条目数pageSize ,计算一下正确的position。@Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("TAG", "position:" + position); ViewHolder vh = null; if (convertView == null) { convertView = mLayoutInflater.inflate(R.layout.item_gridview_header, parent, false); vh = new ViewHolder(); vh.tv = (TextView) convertView.findViewById(R.id.textView); vh.iv = (ImageView) convertView.findViewById(R.id.imageView); convertView.setTag(vh); } else { vh = (ViewHolder) convertView.getTag(); } /** * 在给View绑定显示的数据时,计算正确的position = position + mIndex * mPageSize, */ int pos = position + mIndex * mPageSize; vh.tv.setText(mDatas.get(pos).name); vh.iv.setImageResource(mDatas.get(pos).iconRes); return convertView; }
四:其实第四步不修改,显示也是正常的,但是我觉得应该也要同步修改一下,getItem和getItemId方法,代码一并贴上来。
@Override public Object getItem(int position) { return