最近项目里有用到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); } } }
以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。
本文向大家介绍Android实现ViewPager无限循环效果(二),包括了Android实现ViewPager无限循环效果(二)的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现ViewPager无限循环效果的第二种方式,供大家参考,具体内容如下 原理:在Adapter中将getCount设置为无限大 代码: act_loopviewpager.xml 以上就是本文
本文向大家介绍Android实现ViewPager无限循环效果(一),包括了Android实现ViewPager无限循环效果(一)的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现ViewPager无限循环的具体代码,供大家参考,具体内容如下 方式一: 实现原理: 假设有3张图片,分别是1,2,3,那么就创建5张图片,这5张图片的顺序为:3,1,2,3,1,其中1,2
本文向大家介绍iOS实现无限循环轮播图效果,包括了iOS实现无限循环轮播图效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了iOS实现无限循环轮播图的具体代码,供大家参考,具体内容如下 轮播图基础控件,左滑右滑都能无限循环 预览 思路 (1)在第一张左边加一张最后一张的图片,往左滑到边缘结束后计算偏移量迅速定位成最后一张 (2)总共只有左、中、右三个页面,每次滑动后重新进行数据跟页
我一直在玩React 16.7-alpha中的新钩子系统,当我处理的状态是一个对象或数组时,我陷入了useEffect中的无限循环中。 首先,我使用useState并用一个像这样的空对象启动它: 然后,在useffect中,我使用setObj再次将其设置为空对象。作为第二个参数,我正在传递[obj],希望如果对象的内容没有改变,它不会更新。但它一直在更新。我猜是因为无论内容是什么,它们总是不同的对
本文向大家介绍原生js实现无限循环轮播图效果,包括了原生js实现无限循环轮播图效果的使用技巧和注意事项,需要的朋友参考一下 知识要点 1.实现无限循环的原理: 以偏移的距离来判断是否跳回第一张和最后一张 也可以利用循环判断图片的当前索引值 2.当前图片轮播的圆点变色显示: 因为每次点击index+1 所以当前的index-1就是button的索引 3.实现动画滚动效果: 原理就是把每次的偏移量分为
我想实现一个无限循环数据集 如您所见,这里的主要挑战是方法。如果我在那里放一个足够大的数字,比如1 如果我在那里放一个小数字,比如1或BATCH_SIZE,训练循环中采样的“数据”将定期重复。这不是我想要的,因为我想产生新的数据 我猜过度使用内存的罪魁祸首是堆栈中的某个地方,缓存了一堆东西。随便看看Python的一面,我就不知道在哪里了。 有人能告诉我什么是实现我想要的最好的方法吗?(使用Data