自定义循环滑动的viewpager
今天和大家分享一下如何定制一个可以循环滑动的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的更多相关文章
- android 自定义无限循环播放的viewPager。轮播ViewPager。实现循环播放 广告,主题内容,活动,新闻内容时。
前言 实际项目需要一个 播放广告的控件,可能有多个广告图片.每个一段时间更换该图片.简单来说,就是一个 “循环播放图片”的控件. 间隔时间更换图片 一般来说,图片切换时需要有动画效果 需要支持手势,用 ...
- Android使用ViewPager实现左右循环滑动及轮播效果
边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...
- Android 使用ViewPager实现左右循环滑动图片
ViewPager这个小demo实现的是可以左右循环滑动图片,下面带索引,滑到最后一页在往右滑动就要第一页,第一页往左滑动就到最后一页,先上效果图,用美女图片是我一贯的作风,呵呵 1. 首先看一 ...
- android中无限循环滑动的gallery实例
android中无限循环滑动的gallery实例 1.点击图片有变暗的效果,使用imageview.setAlpha(),并且添加ontouchListener public void init() ...
- viewpage 循环滑动播放图片
一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...
- Android-垂直滑动的ViewPager
该ViewPager和正常的ViewPager的使用方式是一样的,只不过是垂直滑动的. 下面是这个ViewPager的代码 /** * 垂直滑动的ViewPager */ public class V ...
- 关于UIScrollView无限循环滑动
在使用某宝或某东购物的时候,我们会在其首页看到一个可以滑动的版块,这个版块的实现就是一个UIScrollView.在我们使用UIScrollView的时候会发现,滑动到最后的时候,UIScrollVi ...
- android:使用gallery和imageSwitch制作可左右循环滑动的图片浏览器
为了使图片浏览器左右无限循环滑动 我们要自己定义gallery的adapter 假设要想自己定义adapter首先要了解这几个方法 @Override public int getCount() { ...
- andorid自己定义ViewPager之——子ViewPager滑到边缘后直接滑动父ViewPager
近期的项目中,有一个需求要用ViewPager中嵌套ViewPager去实现整个效果.没做不论什么处理做出来后,仅仅能不停的滑动子ViewPager,父ViewPager就无法滑动了,这样肯定是不满足 ...
随机推荐
- 高效率http页面优化法则一【JS对DOM的操作】
高效http页面优化法则一很多人都认为JS的效率太慢了,都不愿意用js来实现相对困难一点的程序逻辑.在这里我要说的是其实js的效率并不慢,慢的是DOM,如果操作好DOM,你的js效率将提高接近千倍(这 ...
- UIView不接受触摸事件的三种情况
1.不接收用户交互 userInteractionEnabled = NO 2.隐藏 hidden = YES 3.透明 alpha = 0.0 ~ 0.01 4. 如果子视图的位置超出了父视图的有效 ...
- java系列-安装MySql(三)
第一大步:MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果是msi格式的可以直接点击安装,按照它给出的安装提示进行安装(相信大家的英文可以看懂英文提示),一般MySQL将会安装 ...
- ORA-22868: 具有 LOB 的表包含有位于不同表空间的段
由于lob对象引起的表空间无法删除.本来是要删除DMS表空间,但是上面有LOB对象,而且表却是在别的表空间DMS4上.解决的办法就是将这些lob移动到DMS4表空间.下面是解决过程 删除用户时报错: ...
- PO、VO、DAO、BO、POJO
一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择.二.VO :(value object) , ...
- git 教程(10)--添加远程库
现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举 ...
- static小结
1.隐藏:编译多个文件时,所有未加static的全局变量.全局函数都具有全局可见性. 如果加了static,就会对其他源文件隐藏,利用这一特性可以在不同文件中定义相同的 变量名或函数名,而不用担心冲突 ...
- UDS帧传输
说明 在UDS协议中,其中有一点我视作为基础,即帧传输.也即是数据传输这一块,在UDS的帧传输中,分为4种: SF单帧 FF第一帧 CF连续帧 FC流控制帧 首先,我们抛开以上的东西,假设一个销售商( ...
- 高性能图片服务器–ZIMG
2011年李彦宏在百度联盟峰会上就提到过互联网的读图时代已经到来1,图片服务早已成为一个互联网应用中占比很大的部分,对图片的处理能力也相应地变成企业和开发者的一项基本技能.需要处理海量图片的典型应用有 ...
- 5.2---小数的二进制表示(CC150)
public static String printBin(double num) { StringBuffer str = new StringBuffer(); str.append('0'); ...