Android 利用ViewPager+GridView,仿美团首页导航栏分类布局界面

先看美团的效果:


再看我们山寨的效果:


最初我是使用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()方法:

@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;
}
在给View绑定显示的数据时,根据当前下标index,和每页显示最大的条目数pageSize ,计算一下正确的position。

四:其实第四步不修改,显示也是正常的,但是我觉得应该也要同步修改一下,getItem和getItemId方法,代码一并贴上来。

@Override
public Object getItem(int position) {
    return 
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值