目前情况
在不修改源码的情况下,当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
总结
希望对大家有帮助,多提意见。近段时间项目很赶,很长时间没看书写博客了。赶项目赶得都麻木了,放松放松,偷偷懒,写写博客吧。