ViewPager实现无限循环

#引言
这两天在项目里有用到ViewPager来做广告运营位展示,看到现在很多APP的广告运营位都是无限循环的,所以就研究了一下这个功能的实现。
#先看看效果
这里写图片描述
从一个方向上一直滑动,么有滑到尽头的感觉,具体是怎么实现的呢?看下面的思路。
#实现思路
这里写图片描述
此处画了一幅图来表达实现无限循环的思路,即在数据起始位置前插入最后一项数据,在最后一项数据后插入第一项数据,当滑动到此处时,更新页面的索引位置就ok了 。
#代码实现
这个方法用于数据处理,其中mediaList是原始数据,newMediaList是处理完的数据,mMediaList是用于页面显示的数据。

public void initItemList(List<MediaIntro> mediaList){
			List<MediaIntro> newMediaList = new ArrayList<MediaIntro>();
			newMediaList.addAll(mediaList);
			if(newMediaList.size() > 1){
				//第0个位最后一个,向左拉动时,可以实现直接滑动到最后一个,最后一个是第0个,可以实现向右滑动的时直接跳到第0个
				newMediaList.add(0,mediaList.get(mediaList.size() -1));
				newMediaList.add(mediaList.get(0));
			}
			mMediaList = newMediaList;
		}

完整的adapter的代码:

public class AdImagePagerAdapter extends RecyclingPagerAdapter{
		private LayoutInflater mInflater;
		private List<MediaIntro> mMediaList = new ArrayList<MediaIntro>();
		
		private boolean isInfiniteLoop; //是否无限循环
		int size;
		
		public AdImagePagerAdapter (LayoutInflater inflater ,List<MediaIntro> mediaList){
			mInflater = inflater;
			isInfiniteLoop = false;
			initItemList(mediaList);
			size = mMediaList.size();
		}
		
		public void initItemList(List<MediaIntro> mediaList){
			List<MediaIntro> newMediaList = new ArrayList<MediaIntro>();
			newMediaList.addAll(mediaList);
			if(newMediaList.size() > 1){
				//第0个位最后一个,向左拉动时,可以实现直接滑动到最后一个,最后一个是第0个,可以实现向右滑动的时直接跳到第0个
				newMediaList.add(0,mediaList.get(mediaList.size() -1));
				newMediaList.add(mediaList.get(0));
			}
			mMediaList = newMediaList;
		}
		
		public MediaIntro getItem(int position){
			return mMediaList.get(position);
		}
		public int getPosition(int position){
			return isInfiniteLoop? position%size:position;
		}
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			final ViewHolder holder;
			final MediaIntro media = getItem(position);
			if(convertView == null){
				holder = new ViewHolder();
				convertView = mInflater.inflate(R.layout.home_ad_item, parent,false);
				holder.mImageView = (ImageView)convertView.findViewById(R.id.homeAdItemImg);
				holder.mTextView = (TextView)convertView.findViewById(R.id.homeAdItemTxt);
				convertView.setTag(holder);
			}else{
				holder=(ViewHolder)convertView.getTag();
			}
			if(media.source.equals(MagicSource.SOURCE_OUT_AD)){
				imageLoader.displayImage(adImageUrl,holder.mImageView,adImageOptions,null,null);
				holder.mTextView.setText("");
				holder.mImageView.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						//广告点击事件
					}
				});
			}else {
				imageLoader.displayImage(media.imgUrl, holder.mImageView,adImageOptions,null,null);
				holder.mTextView.setText(media.desc+"");
				holder.mImageView.setOnClickListener(new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						startMediaDetail(media);
					}
				});
			}
			return convertView;
		}
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return isInfiniteLoop ? Integer.MAX_VALUE : mMediaList.size();
		}
		private class ViewHolder{
			ImageView mImageView = null;
			TextView mTextView = null;
		}
		public boolean isInfiniteLoop(){
			return isInfiniteLoop;
		}
		public AdImagePagerAdapter setInfiniteLoop(boolean isInfiniteLoop){
			this.isInfiniteLoop =isInfiniteLoop;
			return this;
		}
	}

更新页面索引的代码:

@Override
		public void onPageSelected(int position) {
			// TODO Auto-generated method stub
			
			if(adImageAdapter.getCount()>1){ 
				if(position<1){
					position=adImageAdapter.getCount()-2;
					adViewPager.setCurrentItem(adImageAdapter.getCount()-2,false);
				}else if(position > adImageAdapter.getCount()-2){
					position = 1;
					adViewPager.setCurrentItem(1, false);
				}
				setAdPagePointSelected(position-1);
			}
		}

完整的滑动监听器代码

public class OnAdPageChangeListener implements OnPageChangeListener{

		@Override
		public void onPageScrollStateChanged(int arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onPageSelected(int position) {
			// TODO Auto-generated method stub
			
			if(adImageAdapter.getCount()>1){ 
				if(position<1){
					position=adImageAdapter.getCount()-2;
					adViewPager.setCurrentItem(adImageAdapter.getCount()-2,false);
				}else if(position > adImageAdapter.getCount()-2){
					position = 1;
					adViewPager.setCurrentItem(1, false);
				}
				setAdPagePointSelected(position-1);
			}
		}
		
	}

#具体效果
这里写图片描述
哈哈,看上去效果还可以。
#总结
当然肯定还有别的办法来实现,这是我最近用到的实现方式,就把它记录下来。
每天写点代码,挺快乐的,分享出来和大家一起快乐。晚安。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
实现数据无限循环可以通过以下步骤: 1. 在Adapter中重写getCount()方法,将其返回一个较大的值,比如Integer.MAX_VALUE,这样就可以实现数据循环的效果。 2. 在Adapter中重写getItem()方法,将其返回数据集中指定位置的数据,但是要注意,位置需要取余数,即position % data.size(),这样可以保证数据循环。 3. 在ViewPager中重写onPageSelected()方法,当用户滑动到第一个或最后一个数据时,将ViewPager设置为对应的位置,这样就可以实现无限循环的效果。 以下是示例代码: ``` public class MyPagerAdapter extends PagerAdapter { private List<Data> mDataList; public MyPagerAdapter(List<Data> dataList) { mDataList = dataList; } @Override public int getCount() { return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { View itemView = LayoutInflater.from(container.getContext()).inflate(R.layout.item_viewpager, container, false); TextView textView = itemView.findViewById(R.id.tv_data); Data data = mDataList.get(position % mDataList.size()); textView.setText(data.getData()); container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } public class MainActivity extends AppCompatActivity { private ViewPager mViewPager; private List<Data> mDataList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initViewPager(); } private void initData() { for (int i = 0; i < 10; i++) { mDataList.add(new Data("Data " + i)); } } private void initViewPager() { mViewPager = findViewById(R.id.view_pager); mViewPager.setAdapter(new MyPagerAdapter(mDataList)); mViewPager.setCurrentItem(Integer.MAX_VALUE / 2); mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { if (position == 0) { mViewPager.setCurrentItem(Integer.MAX_VALUE / 2); } else if (position == Integer.MAX_VALUE - 1) { mViewPager.setCurrentItem(Integer.MAX_VALUE / 2); } } @Override public void onPageScrollStateChanged(int state) { } }); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值