ViewPager实现左右无限循环效果

本文介绍了如何在ViewPager中实现真正的左右无限循环效果。通过在显示的视图中添加额外的头尾节点,实现了在滑动边界时平滑过渡,避免了常规方法中的边界限制问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ViewPager自身并不支持左右无限循环的功能,在网上找了很多天,发现基本都是一个原理,就是实现一种假的无限循环,取一种最大值的思路,这一种方案在上一篇中实现过,并没有真正达到左右无限循环,只是一般情况下,很难达到边界(不可滑动)的情况。下面记录一下另一种方案,网上号称是真正的无限循环。

用于显示的mViews,比数据源mList,多了两个节点元素(头节点0:b和尾节点5:e用于跳转)
下图的不带箭头的红线,是mViews根据mList初始化的情况;带箭头的红线是跳转的情况。


首先还是布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewpager"
        android:background="#33000000"
        android:orientation="vertical"
        android:padding="5dip" >

        <TextView
            android:id="@+id/tv_image_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="第一个引导页面"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

        <LinearLayout
            android:id="@+id/ll_points"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dip"
            android:layout_gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

接下来是MainActivity:

package com.example.viewpagertest;

import java.util.ArrayList;
import java.util.List;

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.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnPageChangeListener {

	private List<ImageView> imageViewList;
	private ViewPager mViewPager;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setView();
		initView();
	}

	public void setView() {
		setContentView(R.layout.activity_splash_viewpager);

	}

	public void initView() {
		mViewPager = (ViewPager) findViewById(R.id.viewpager);
    	prepareData();
    	
    	ViewPagerAdapter adapter = new ViewPagerAdapter();
    	mViewPager.setAdapter(adapter);
    	mViewPager.setOnPageChangeListener(this);
	}
	
	 private void prepareData() {
	    	imageViewList = new ArrayList<ImageView>();
	    	int[] imageResIDs = getImageResIDs();
	    	ImageView iv;
	    	for (int i = 0; i < imageResIDs.length; i++) {
				iv = new ImageView(this);
				iv.setBackgroundResource(imageResIDs[i]);
				imageViewList.add(iv);
				
			}
	    }
	    
	 /**
	  * 在此处本来是5张图片,现在在数组首尾各加了一张图
	  * @return
	  */
	    private int[] getImageResIDs() {
	    	return new int[]{
	    			R.drawable.pic_02,
	    			R.drawable.bg1,
	    			R.drawable.bg2,
	    			R.drawable.bg3,
	    			R.drawable.pic_01,
	    			R.drawable.pic_02,
	    			R.drawable.bg1,

	    	};
	    }
	    
	    class ViewPagerAdapter extends PagerAdapter {

			@Override
			public int getCount() {
				return imageViewList.size();
			}

			/**
			 * 判断出去的view是否等于进来的view 如果为true直接复用
			 */
			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				return arg0 == arg1;
			}

			/**
			 * 销毁预加载以外的view对象, 会把需要销毁的对象的索引位置传进来就是position
			 */
			@Override
			public void destroyItem(ViewGroup container, int position, Object object) {
				container.removeView(imageViewList.get(position));
			}

			/**
			 * 创建一个view
			 */
			@Override
			public Object instantiateItem(ViewGroup container, int position) {
				container.addView(imageViewList.get(position));
				return imageViewList.get(position);
			}
	    }

		@Override
		public void onPageScrollStateChanged(int arg0) {
			
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
			
		}

		@Override
		public void onPageSelected(int position) {
			if ( imageViewList.size() > 1) { //多于1,才会循环跳转
				if ( position < 1) { //首位之前,跳转到末尾(N)
					position = 5; 
					mViewPager.setCurrentItem(position,false);
				} else if ( position > 5) { //末位之后,跳转到首位(1)
					mViewPager.setCurrentItem(1,false); //false:不显示跳转过程的动画
					position = 1;
				}
			}	
		}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

}

mViewPager.setCurrentItem(1,false); //false:不显示跳转过程的动画

上面的代码只是一个简单的Demo,如果不将跳转动画去掉的话,首尾页跳转的时候过渡效果会很不自然。



评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值