前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >无尽的循环ViewPager

无尽的循环ViewPager

作者头像
全栈程序员站长
发布2022-07-06 14:07:00
4680
发布2022-07-06 14:07:00
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是全栈君。

现在的情况

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

(以上全是废话)

设想

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

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

优化

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

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

无尽的循环ViewPager
无尽的循环ViewPager

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

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

无尽的循环ViewPager
无尽的循环ViewPager

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

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

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

代码分析

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

关键代码例如以下:

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

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

条件推断:

代码语言:javascript
复制
	@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);
	}

跳转:

代码语言:javascript
复制
	@Override
	public void onPageScrollStateChanged(int pState) {
		if (ViewPager.SCROLL_STATE_IDLE == pState) {
			if (mIsChanged) {
				mIsChanged = false;
				mViewPager.setCurrentItem(mCurrentPagePosition, false);
			}
		}
	}

完整的逻辑例如以下:

代码语言:javascript
复制
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

总结

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

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

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

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

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/117016.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 现在的情况
  • 设想
  • 优化
  • 代码分析
  • 总结
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档