现在的情况

不改变的源代码,什么时候ViewPager滑动到最后item的时候,他就无法再往右滑动;当ViewPager滑动到第一个item的时候,他也无法再往前滑动。

(以上全是废话)

设想

我们能够这样想。当滑动到最后一个的时候,我们让他跳转到第一个,这样他就能够继续往后滑动了,这样就达到了我们想要的循环滑动。

尽管功能上是循环了,可是实际显示的时候会在最后一个和第一个之间自己主动跳转。

优化

我们能够在原来的链表中首尾各添加一个假的item。用多余的两个item来作跳转的动作,这样就能够避免出现自己主动跳转的错误画面了。

我们要显示的是以下A、B、C画面。位置各自是0、1、2.

实际上,我们加入数据的时候,多加入了2个。

在位置0加入了最后一个界面C,在位置4加入了第一个界面A。

当界面滑动到位置3的时候,他还能够往右滑动,这样给人的感觉就是循环的。但,当滑动到位置4的时候。他右边没有了,这样岂不是露馅了?所以,当滑动到位置4的时候。立马跳转到位置1。

由于他们是相同的数据,所以从显示效果是看不出跳转了的。这样实际上我们就变成了位置1,这样就又能够继续往右滑动了。

反复上面条件的推断。这样就实现了往右的循环。往左也是相同的道理。

代码分析

在onPageSelected里面做条件推断,在onPageScrollStateChanged里面做跳转。

关键代码例如以下:

初始化。首尾各添加一个item。

// 添加第1个界面,实际上他显示的是最后一个界面
addTextView(POINT_LENGTH - 1);
// 添加实际显示的2、3、4界面
for (int i = 0; i < 3; i++) {
addTextView(i);
addPoint(i);
}
// 添加最后的第5个界面,实际上他显示的是第一个界面
addTextView(0);

条件推断:

	@Override
public void onPageSelected(int pPosition) {
mIsChanged = true;
if (pPosition > POINT_LENGTH) {
mCurrentPagePosition = FIRST_ITEM_INDEX;
} else if (pPosition < FIRST_ITEM_INDEX) {
mCurrentPagePosition = POINT_LENGTH;
} else {
mCurrentPagePosition = pPosition;
}
Log.i(TAG,"当前的位置是"+mCurrentPagePosition);
setCurrentDot(mCurrentPagePosition);
}

跳转:

	@Override
public void onPageScrollStateChanged(int pState) {
if (ViewPager.SCROLL_STATE_IDLE == pState) {
if (mIsChanged) {
mIsChanged = false;
mViewPager.setCurrentItem(mCurrentPagePosition, false);
}
}
}

完整的逻辑例如以下:

package com.ahacool.circleviewpager;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView; /**
* @ClassName MainActivity
* @Description 循环滑动viewpager的一种方法,滑动非常流畅。实现方法:在实际显示的界面头和尾分别添加一个界面。 * @author Moto
* @date 2014 2014-7-18
*
*/
public class MainActivity extends Activity implements OnPageChangeListener { private ViewPager mViewPager;
private ViewGroup mPointViewGroup;
private ArrayList<View> mViewPagerList;
private boolean mIsChanged = false;
private int mCurrentPagePosition = FIRST_ITEM_INDEX;
private int mCurrentIndex;
private static final int POINT_LENGTH = 3;
private static final int FIRST_ITEM_INDEX = 1;
private static final String TAG = "MOTO"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
} private void initUI() {
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mPointViewGroup = (ViewGroup) findViewById(R.id.point_layout); mViewPagerList = new ArrayList<View>();
// 添加第1个界面,实际上他显示的是最后一个界面
addTextView(POINT_LENGTH - 1);
// 添加实际显示的2、3、4界面
for (int i = 0; i < 3; i++) {
addTextView(i);
addPoint(i);
}
// 添加最后的第5个界面,实际上他显示的是第一个界面
addTextView(0); PagerAdapter pagerAdapter = new CustomPagerAdapter(mViewPagerList);
mViewPager.setAdapter(pagerAdapter);
mViewPager.setOnPageChangeListener(this);
mViewPager.setCurrentItem(mCurrentPagePosition, false);
} private void addTextView(int pIndex) {
TextView textview = new TextView(this);
textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
textview.setGravity(Gravity.CENTER);
textview.setText("这是第" + (pIndex + 1) + "个页面");
textview.setTextSize(50);
mViewPagerList.add(textview);
} private void addPoint(int pIndex) {
ImageView pointImageView = new ImageView(this);
LayoutParams layoutParams = new LayoutParams(20, 20);
layoutParams.setMargins(10, 0, 10, 0);
pointImageView.setLayoutParams(layoutParams);
pointImageView.setBackgroundResource(R.drawable.point_style);
if (0 == pIndex) {
pointImageView.setEnabled(false);
}
mPointViewGroup.addView(pointImageView);
} private void setCurrentDot(int positon) {
// 界面实际显示的序号是第1, 2, 3。而点的序号应该是0, 1, 2.所以减1.
positon = positon - 1;
if (positon < 0 || positon > mViewPagerList.size() - 1 || mCurrentIndex == positon) {
return;
}
mPointViewGroup.getChildAt(positon).setEnabled(false);
mPointViewGroup.getChildAt(mCurrentIndex).setEnabled(true);
mCurrentIndex = positon;
} @Override
public void onPageScrollStateChanged(int pState) {
if (ViewPager.SCROLL_STATE_IDLE == pState) {
if (mIsChanged) {
mIsChanged = false;
mViewPager.setCurrentItem(mCurrentPagePosition, false);
}
}
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override
public void onPageSelected(int pPosition) {
mIsChanged = true;
if (pPosition > POINT_LENGTH) {
mCurrentPagePosition = FIRST_ITEM_INDEX;
} else if (pPosition < FIRST_ITEM_INDEX) {
mCurrentPagePosition = POINT_LENGTH;
} else {
mCurrentPagePosition = pPosition;
}
Log.i(TAG,"当前的位置是"+mCurrentPagePosition);
setCurrentDot(mCurrentPagePosition);
} }

源代码下在地址:https://github.com/bird7310/Demos.git

总结

希望对大家有帮助。多提意见。

近段时间项目非常赶,非常长时间没看书写博客了。

赶项目赶得都麻,放松。偷偷懒。写博客是。

版权声明:本文博主原创文章,博客,未经同意不得转载。

无尽的循环ViewPager的更多相关文章

  1. Android循环ViewPager(二)

    上午没事写了一篇,下午有事,晚上回来看看感觉写的差点意思,上篇文章大概的关于循环是自己添加了两个空的View,看到网上还有一种就是在自定义的Adapter中getCount中返回最大值,然后destr ...

  2. 循环viewpager

    如果viewpager listadapter小于三个.用这个移除异常. for (View view : viewList) {             ViewGroup p = (ViewGro ...

  3. ViewPager 无限循环

    Overview 我们在使用ViewPager来制作图片轮播的时候,常常为ViewPager不能一直无限循环的问题所苦恼.对于这个问题,目前从网上找到了两个思路来解决: 将 ViewPager 的Co ...

  4. 【NodeJS线程】Boss和他的职员们

    >>>[说明]还是一如既往的,这篇文章是从我的个人博客里挪过来的.原文参见:http://www.jscon.co/coding/frontend/nodejs_fork_child ...

  5. node 学习笔记 - Modules 模块加载系统 (1)

    本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html 用了这么久的 require,但却没有系统的学习过 n ...

  6. [转载] Python的GIL是什么鬼,多线程性能究竟如何

    原文: http://cenalulu.github.io/python/gil-in-python/ GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器( ...

  7. lintcode:快乐数

    快乐数 写一个算法来判断一个数是不是"快乐数". 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是 ...

  8. Project Euler 92:Square digit chains 平方数字链

    题目 Square digit chains A number chain is created by continuously adding the square of the digits in ...

  9. Happy Number——LeetCode

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

随机推荐

  1. 从尾到头打印链表--《剑指offer》

    题目:非常easy,就是题目,将链表从尾到头打印出来. 可能我们首先想到的是将链表进行遍历,将之前的訪问的数据进行保存,最后进行反向输出,但是保存数据的空间是个问题:或者是我们将整个链表进行反向操作, ...

  2. Working with forms

    翻译 Django文档 Version 1.5 https://docs.djangoproject.com/en/1.5/topics/forms Working with forms 关于此文章: ...

  3. Android 通过调用系统,如接口 谷歌语音、百度语音、科大讯飞语音等语音识别方法对话框

    现在app在发展过程中会集成一些语音识别功能,不具有其自己的显影剂一般正在开发的语音识别引擎,所以在大多数情况下,它是选择一个成熟的语音识别引擎SDK集成到他们的app在. 平时,这种整合被分成两个, ...

  4. java IO流文件的读写具体实例

    IO流的分类:1.根据流的数据对象来分:高端流:所有的内存中的流都是高端流,比如:InputStreamReader  低端流:所有的外界设备中的流都是低端流,比如InputStream,Output ...

  5. Git在下搭建下环境的工具

    (本文稿来自:http://www.open-open.com/news/view/55387) Git是一个快速,可扩展的,分布式的版本控制系统.Git服务器起初是专为Linux开发,后来移植至Wi ...

  6. 内网port映射具体解释(花生壳)

    关于怎样建立服务器的解答. 一.花生壳的作用 首先,我们先来了解一下花生壳的究竟有什么作用.由于ADSL每次拨号上网所获得的IP地址每次都是不同的,花生壳起到的作用就是方便用户訪问我们的server( ...

  7. 二十7天 春雨滋润着无形 —Spring依赖注入

    6月11日,明确."夏条绿已密,朱萼缀明鲜.炎炎日正午,灼灼火俱燃." IT人习惯把详细的事物加工成的形状一致的类.正是这种一致,加上合适的规范.才干彰显对象筋道的牙感和bean清 ...

  8. 漫游Kafka介绍章节简介

    原文地址:http://blog.csdn.net/honglei915/article/details/37564521 介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息 ...

  9. PageRank算法MapReduce实现

    如果你现在需要计算网页的排名只有4一:数据如下面的: baidu 10.00 google,sina,nefu google 10.00 baidu sina 10.00 google nefu 10 ...

  10. IM设计与实现的系统模块的聊天记录

    到非常多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供须要的朋友參考下. 一.整体设计 1.存储位 ...