自定义循环滑动的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就无法滑动了,这样肯定是不满足 ...
随机推荐
- jQuery源码-jQuery.fn.attr与jQuery.fn.prop
jQuery.fn.attr.jQuery.fn.prop的区别 假设页面有下面这么个标签,$('#ddd').attr('nick').$('#ddd').prop('nick')分别会取得什么值? ...
- 在hexo静态博客中利用d3-cloud来展现标签云
效果: http://lucyhao.com/tags/ hexo自带的tag cloud的标签展现不太美观,想能够展现出“云”效果的标签.在网上找到了d3-cloud这个项目,github地址:ht ...
- ubuntu安装ssh
为了解决远程连接ubuntu服务器控制端,方便操作.ubuntu不同的版本安装方式一致!首先在ubuntu服务器下安装SSH服务linux安装命令:sudo apt-get install opens ...
- ThinkPHP3.2.3 安装教程
本文以 Windows 平台为例 安装前准备:Windows操作系统的电脑,php编程环境(配置好了Apache.MySql.php).推荐wampserver. 待安 ...
- 【GXZ的原创】C++小游戏——五子棋
前些时候考完试自己编的带有胜负判定的五子棋. 操作方法:WSAD或↑↓←→移动下棋位置,Space或Enter放置. 如果游戏出现bug,欢迎大家在评论区反馈. #include <stdio. ...
- java遍历map的四种方式
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- lua操作json,mysql,redis等
==========================example for lua json======================= local cjson = require("cj ...
- C++ 错误总结
1.出现不完全的类型‘class CJdThread’的非法使用或前向声明 src/../include/ComCommon.h:37:27: 错误:对不完全的类型‘class CJdThread’的 ...
- Javascript高级程序设计——函数声明与函数表达式的区别
在Javascript中,函数是Functioin类型的实例,所以函数也具备属性和方法,因为函数是对象,所以函数名自然就是指向对象的指针啦. 函数可以通过声明语法和表达式来定义: 声明:functio ...
- FineUI第九天---表单验证
表单验证 步骤: 1.比如为TextBox设置Required=”true”或者ShowRedStar=”true”两个属性,表示此输入为必填项,并且在标签的后面显示一个红色的星号提示. 2.Vali ...