今天和大家分享一下如何定制一个可以循环滑动的viewpager。其实今天更重要的提供一种组件化思想,当然你可以理解为面向对象思想。

吐槽一下网上流行的实现方式吧(为了方便说明,下文称之为方式A),方式A是重写adapter的getCount方法,返回一个很大的数(值为max),adapter中的getView方法中的position重新根据实际数量取模,把viewpager设置在max二分之一的位置。因为这个值很大所以基本不可能滑动到position=0或者position=max的位置,不过确切来说这并不是无限循环,采用脚本之类的应该可以滑动到边界(没有试验过)。

我们的需求

快速把之前viewpager相关的代码改成无限循环。

这个需求很简单就是在已有的代码上完成无限循环。当然你可以根据方式A来完成,它是通过适配器来完成无限循环的,不过这种方式你需要改的代码并不少,毕竟你得改适配器。

本文需要提供的方式B就登场了,好处在于不用改你的adapter,只需要把你的viewpager改成本文中的组件CycleViewPager就可以了,其他的都不用改。

原理

CycleViewPager继承ViewPager。当向右翻页(文中指的向右翻页是指手指由右向左滑,向左翻页反之),数据滑动到最后一条数据时调用setCurrentItem(0)返回第一条,当向左翻页,数据滑动到第一条数据时setCurrentItem(getCount()-1)返回到最后一条数据。在设置数据的时候需要多生成两条数据,比如原始数据是[a,b,c,d,e],那么生成的数据为[e,a,b,c,d,e,a],原始数据第一条前面加了最后一条数据e,原始数据的最后一条的后面加了原始数据的第一条数据a。从a滑到e时,继续向右翻页那么就到了数据a(最右边的那个a),停止滑动时调用setCurrentItem(1)返回第一条数据a(最左边的那个a);从e滑动到a时,继续向左翻页那么就到了数据e(做左边的那个e),停止滑动时调用setCurrentItem(5)。

直接上代码

 package com.vane.widget.cycleviewpager;

 import android.content.Context;
import android.database.DataSetObserver;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup; public class CycleViewPager extends ViewPager { private InnerPagerAdapter mAdapter; public CycleViewPager(Context context) {
super( context);
setOnPageChangeListener( null);
} public CycleViewPager(Context context, AttributeSet attrs) {
super( context, attrs);
setOnPageChangeListener( null);
} @Override
public void setAdapter(PagerAdapter arg0) {
mAdapter = new InnerPagerAdapter( arg0);
super.setAdapter( mAdapter);
setCurrentItem( 1);
} @Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
super.setOnPageChangeListener( new InnerOnPageChangeListener( listener));
} private class InnerOnPageChangeListener implements OnPageChangeListener { private OnPageChangeListener listener;
private int position; public InnerOnPageChangeListener(OnPageChangeListener listener) {
this.listener = listener;
} @Override
public void onPageScrollStateChanged(int arg0) {
if(null != listener) {
listener.onPageScrollStateChanged( arg0);
}
if(arg0 == ViewPager.SCROLL_STATE_IDLE) {
if(position == mAdapter.getCount() - 1) {
setCurrentItem( 1, false);
}
else if(position == 0) {
setCurrentItem( mAdapter.getCount() - 2, false);
}
}
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if(null != listener) {
listener.onPageScrolled( arg0, arg1, arg2);
}
} @Override
public void onPageSelected(int arg0) {
position = arg0;
if(null != listener) {
listener.onPageSelected( arg0);
}
}
} private class InnerPagerAdapter extends PagerAdapter { private PagerAdapter adapter; public InnerPagerAdapter(PagerAdapter adapter) {
this.adapter = adapter;
adapter.registerDataSetObserver( new DataSetObserver() { @Override
public void onChanged() {
notifyDataSetChanged();
} @Override
public void onInvalidated() {
notifyDataSetChanged();
} });
} @Override
public int getCount() {
return adapter.getCount() + 2;
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return adapter.isViewFromObject( arg0, arg1);
} @Override
public Object instantiateItem(ViewGroup container, int position) {
if(position == 0) {
position = adapter.getCount() - 1;
}
else if(position == adapter.getCount() + 1) {
position = 0;
}
else {
position -= 1;
}
return adapter.instantiateItem( container, position);
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
adapter.destroyItem( container, position, object);
} }
}

如何使用

使用方法和viewPager是一样一样的,你就认为是viewpager来使用就可以了。源码你可以在github上取https://github.com/vanezkw/cycleviewpager.git

总结

源码中大家也都看到了没有什么特别的其实就是平时讲的设计模式。之前提到的方式A个人认为并不完全是面向对象的方式,这个当然也看大家如何理解。

自定义循环滑动的viewpager的更多相关文章

  1. android 自定义无限循环播放的viewPager。轮播ViewPager。实现循环播放 广告,主题内容,活动,新闻内容时。

    前言 实际项目需要一个 播放广告的控件,可能有多个广告图片.每个一段时间更换该图片.简单来说,就是一个 “循环播放图片”的控件. 间隔时间更换图片 一般来说,图片切换时需要有动画效果 需要支持手势,用 ...

  2. Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...

  3. Android 使用ViewPager实现左右循环滑动图片

    ViewPager这个小demo实现的是可以左右循环滑动图片,下面带索引,滑到最后一页在往右滑动就要第一页,第一页往左滑动就到最后一页,先上效果图,用美女图片是我一贯的作风,呵呵 1.    首先看一 ...

  4. android中无限循环滑动的gallery实例

    android中无限循环滑动的gallery实例 1.点击图片有变暗的效果,使用imageview.setAlpha(),并且添加ontouchListener public void init() ...

  5. viewpage 循环滑动播放图片

    一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...

  6. Android-垂直滑动的ViewPager

    该ViewPager和正常的ViewPager的使用方式是一样的,只不过是垂直滑动的. 下面是这个ViewPager的代码 /** * 垂直滑动的ViewPager */ public class V ...

  7. 关于UIScrollView无限循环滑动

    在使用某宝或某东购物的时候,我们会在其首页看到一个可以滑动的版块,这个版块的实现就是一个UIScrollView.在我们使用UIScrollView的时候会发现,滑动到最后的时候,UIScrollVi ...

  8. android:使用gallery和imageSwitch制作可左右循环滑动的图片浏览器

    为了使图片浏览器左右无限循环滑动 我们要自己定义gallery的adapter 假设要想自己定义adapter首先要了解这几个方法 @Override public int getCount() { ...

  9. andorid自己定义ViewPager之——子ViewPager滑到边缘后直接滑动父ViewPager

    近期的项目中,有一个需求要用ViewPager中嵌套ViewPager去实现整个效果.没做不论什么处理做出来后,仅仅能不停的滑动子ViewPager,父ViewPager就无法滑动了,这样肯定是不满足 ...

随机推荐

  1. C++你不知道的那些事儿—C++语言的15个晦涩特性

    这个列表收集了 C++ 语言的一些晦涩(Obscure)特性,是我经年累月研究这门语言的各个方面收集起来的.C++非常庞大,我总是能学到一些新知识.即使你对C++已了如指掌,也希望你能从列表中学到一些 ...

  2. netstat命令的常见用法(转)

    netstat 的10个基本用法 Netstat 简介 Netstat 是一款命令行工具,可用于列出系统上所有的网络套接字连接情况,包括 tcp, udp 以及 unix 套接字,另外它还能列出处于监 ...

  3. sql批量更换dedecms文章来源和作者

    前面写了一篇修改dedecms默认文章来源 "未知"改为关键词,那个是修改以后发布的文章“来源”才会变成自己设定的关键词,如果修改之前已经有很多文章了,那些文章“来源”还是显示“未 ...

  4. 天翼宽带政企网关B2-1P 如何获得超级管理员账号?

    RT 用useradmin没办法做NAT,想进telecomadmin里面看看,,,,,并且已经使用过nE7jA%5m这个密码登录,没有用! 求办法!!! 最佳答案 查找超级管理员密码方法: 1.用光 ...

  5. linux下svn命令使用大全

    最近经常使用svn进行代码管理,这些命令老是记不住,得经常上网查,终于找了一个linux下svn命令使用大全:1.将文件checkout到本地目录 svn checkout path(path是服务器 ...

  6. Javascript高级程序设计——this、闭包、函数表达式

    在javascript中函数声明会被提升,而函数表达式不会被提升.当函数执行时,会创建一个执行环境和相应的作用域链,然后利用arguments和其他的命名参数的值来初始化函数的活动对象,作用域链链中所 ...

  7. Javascript高级程序设计——面向对象小结

    ECMAScript支持面向对象编程,对象可以在代码执行时创建,具有动态扩展性而非严格意义上的实体. 创建对象方法: 工厂模式:简单的函数创建引用类型 构造函数模式:可以创建自定义引用类型,可以想创建 ...

  8. Javascript包含对象的数组去重

    Array.prototype.clearRepeat = function(){ var result = [], obj = {}; for(var i = 0; i < this.leng ...

  9. BZOJ1030——文本生成器

    给你若干给字符串,再给你一个m,问长度是m的字符串中包含给定字符串的数量mod 10007是多少 这个拿过来啥思路也没有,后来还是看了题解,才知道,原来,原来....那个带fail的Trie还可以搞别 ...

  10. CSS3-transform,2D动画实例

    对元素进行移动.缩放.转动.拉长 或 拉伸 全部都需要加前缀. Transform-2D转换方法:rotate()旋转.scale()缩放.skew()扭曲/倾斜.translate()位移.matr ...