巧用ViewPager实现日历场景

巧用ViewPager实现日历场景

android中用ViewPager实现循环滑动 一文的结尾我们曾留了个小问题:

提个小问题:如果换一个场景,比如在日历中,我们每滑一下就显示下一个月或上一个月的日历,一般做个日历的话都要可以查询上百年的日期吧,如果使用上述方法,难道我们要传N多个view到ViewPagerAdapter里面吗?显然这是不可能的。如果只用三个view呢,让它们循环使用,这也有个问题,你怎么知道它滑到哪年哪月了呢?难道要自己用个计数器把它记起来?会不会太麻烦?下一篇来讲讲如何解决这个问题。

那么今天就来看看怎么解决这个问题。显然传n个view的情况是不现实的,所以放弃。接下来看看第二种方案。

使用循环是值得考虑的,循环可以节省很多资源,也基本上能实现我们的需求。只是有个计数的问题我们需要再考虑一下,看有没有比使用计数器更简便的方法来实现。一般情况下,我们需要显示几个view就传几个view到viewPagerAdapter当中,如我们要显示100个月的日历,那么按一般情况下传100个view进去,每个view代表一个月的日历。这样viewPagerAdapter中的每个position所对应的view就是月份数,不需要计数。那么很自然我们就会想到在getCount()方法中返回我们要显示的月份的个数,然后只传一个view到adapter中,每个月的日历都复用这个view,然后动态加载数据,由于position跟月份是一一对应的,所以就不需要额外的计数器来记月份了。利用这个position就可以知道我们要加载哪个月份的数据了。这样一来,计数的问题就解决了。

当然了,在实际操作时由于需要循环,只传一个view是实现不了的,还要加上头尾两个view(原因请看android中用ViewPager实现循环滑动 一文),因此总共只要传3个view到viewPagerAdapter中就可以了,实现了占用资源的最小化,代码也简洁易懂。

好,大体的思路就是这样,下面来看看代码:

1、在viewPagerAdapter中的getCount()方法返回要显示的月份个数,另外加上两个用于循环的view所占的位置
@Override
public int getCount() {
    // 这里作为示例我们只显示12个月的日期,另外加上两个用于循环的view
    return 12 + 2;
}
2、在instantiateItem(ViewGroup container, int position)方法中复用我们传入的view,也即是日历的布局。然后根据position动态绑定要显示的数据。
@Override
public Object instantiateItem(ViewGroup container, int position) {
    // 复用日历布局,动态改变布局展示的数据
    int index = position % mViews.size();
    View v = mViews.get(index);
    if (container.indexOfChild(v) != -1) {
        container.removeView(v);
    }
    container.addView(v);
    // 动态改变View里面的显示内容
    bindData(v, position);
    return v;
}
3、绑定数据,根据position就可以知道我们要显示哪个月份的数据,要注意一点的就是在一头一尾两个位置时,要分别设置最后一个月份与第一个月份的数据,本例中position等于1-12时显示1-12月的数据,等于0时显示12月份数据,等于13时显示1月份数据
/**
 * 绑定数据
 * @param v
 * @param position
 */
private void bindData(View v, int position) {
    // 这里只要根据position就可以知道要显示哪个月的内容了,而不必额外记住当前要显示什么内容
    TextView tv = (TextView) v;
    String s;
    if (position == 0) {
        s = (getCount() - 2) + "";
    } else if (position == getCount() - 1) {
        s = "1";
    } else {
        s = position + "";
    }
    tv.setText("2017年" + s + "月");
}
4、由于第2步中我们删除了container中与新添加进来的veiw重复的view,所以在destroyItem方法不要再去删除任何view,保持为空方法即可。
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}

这样主要的代码就完成了。

来看下效果:


最后,上源码:

demo源码:https://github.com/MingHuang1024/FlexiableViewPager



由于水平有限,如果文中存在错误之处,请大家批评指正,欢迎大家一起来分享、探讨!

博客:http://blog.csdn.net/MingHuang2017

GitHub:https://github.com/MingHuang1024

Email:MingHuang1024@foxmail.com

微信:724360018

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值