android viewpager自动循环滑动,Android ViewPager实现无限循环效果

最近项目里有用到ViewPager来做广告运营位展示,看到现在很多APP的广告运营位都是无限循环的,所以就研究了一下这个功能的实现。

先看看效果

从一个方向上一直滑动,么有滑到尽头的感觉,具体是怎么实现的呢?看下面的思路。

实现思路

此处画了一幅图来表达实现无限循环的思路,即在数据起始位置前插入最后一项数据,在最后一项数据后插入第一项数据,当滑动到此处时,更新页面的索引位置就ok了 。

代码实现

这个方法用于数据处理,其中mediaList是原始数据,newMediaList是处理完的数据,mMediaList是用于页面显示的数据。

public void initItemList(List mediaList){

List newMediaList = new ArrayList();

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 mMediaList = new ArrayList();

private boolean isInfiniteLoop; //是否无限循环

int size;

public AdImagePagerAdapter (LayoutInflater inflater ,List mediaList){

mInflater = inflater;

isInfiniteLoop = false;

initItemList(mediaList);

size = mMediaList.size();

}

public void initItemList(List mediaList){

List newMediaList = new ArrayList();

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软件编程有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 ViewPager 的循环滑动,可以通过以下步骤: 1. 继承 ViewPager 类,重写 `onTouchEvent` 方法,使其支持循环滑动。 ```java public class LoopViewPager extends ViewPager { public LoopViewPager(Context context) { super(context); } public LoopViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { stopAutoScroll(); } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { startAutoScroll(); } return super.onTouchEvent(event); } } ``` 2. 重写 `onMeasure` 方法,使其支持 wrap_content。 ```java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if (h > height) { height = h; } } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } ``` 3. 重写 `setAdapter` 方法,使其支持循环滑动。 ```java @Override public void setAdapter(PagerAdapter adapter) { super.setAdapter(adapter); setCurrentItem(0); } @Override public void setCurrentItem(int item) { int realCount = getRealCount(); if (realCount == 0) { super.setCurrentItem(item); return; } int position = getRealPosition(item); super.setCurrentItem(position); } private int getRealCount() { PagerAdapter adapter = getAdapter(); if (adapter == null) { return 0; } return adapter.getCount(); } private int getRealPosition(int position) { int realCount = getRealCount(); if (realCount == 0) { return 0; } return position % realCount; } ``` 4. 在 `onPageSelected` 回调中处理循环滑动的逻辑。 ```java @Override public void onPageSelected(int position) { int realCount = getRealCount(); if (realCount == 0) { return; } int realPosition = getRealPosition(position); if (realPosition == 0) { setCurrentItem(realCount, false); } else if (realPosition == realCount - 1) { setCurrentItem(1, false); } } ``` 5. 在 `startAutoScroll` 和 `stopAutoScroll` 方法中处理自动滑动的逻辑。 ```java private void startAutoScroll() { stopAutoScroll(); mHandler.postDelayed(mAutoScrollTask, mInterval); } private void stopAutoScroll() { mHandler.removeCallbacks(mAutoScrollTask); } private Runnable mAutoScrollTask = new Runnable() { @Override public void run() { int currentItem = getCurrentItem(); setCurrentItem(currentItem + 1, true); mHandler.postDelayed(this, mInterval); } }; ``` 完整的实现代码如下: ```java public class LoopViewPager extends ViewPager { private static final int DEFAULT_INTERVAL = 3000; private Handler mHandler = new Handler(); private int mInterval = DEFAULT_INTERVAL; public LoopViewPager(Context context) { super(context); init(); } public LoopViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { setPageTransformer(true, new DefaultTransformer()); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { stopAutoScroll(); } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { startAutoScroll(); } return super.onTouchEvent(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if (h > height) { height = h; } } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override public void setAdapter(PagerAdapter adapter) { super.setAdapter(adapter); setCurrentItem(0); } @Override public void setCurrentItem(int item) { int realCount = getRealCount(); if (realCount == 0) { super.setCurrentItem(item); return; } int position = getRealPosition(item); super.setCurrentItem(position); } @Override public void setCurrentItem(int item, boolean smoothScroll) { int realCount = getRealCount(); if (realCount == 0) { super.setCurrentItem(item, smoothScroll); return; } int position = getRealPosition(item); super.setCurrentItem(position, smoothScroll); } @Override public int getCurrentItem() { int realCount = getRealCount(); if (realCount == 0) { return super.getCurrentItem(); } int position = super.getCurrentItem(); return getRealPosition(position); } private int getRealCount() { PagerAdapter adapter = getAdapter(); if (adapter == null) { return 0; } return adapter.getCount(); } private int getRealPosition(int position) { int realCount = getRealCount(); if (realCount == 0) { return 0; } return position % realCount; } @Override public void onPageSelected(int position) { int realCount = getRealCount(); if (realCount == 0) { return; } int realPosition = getRealPosition(position); if (realPosition == 0) { setCurrentItem(realCount, false); } else if (realPosition == realCount - 1) { setCurrentItem(1, false); } } public void setInterval(int interval) { mInterval = interval; } public void startAutoScroll() { stopAutoScroll(); mHandler.postDelayed(mAutoScrollTask, mInterval); } public void stopAutoScroll() { mHandler.removeCallbacks(mAutoScrollTask); } private Runnable mAutoScrollTask = new Runnable() { @Override public void run() { int currentItem = getCurrentItem(); setCurrentItem(currentItem + 1, true); mHandler.postDelayed(this, mInterval); } }; private static class DefaultTransformer implements ViewPager.PageTransformer { @Override public void transformPage(View page, float position) { if (position < -1) { page.setAlpha(0); } else if (position <= 1) { float scaleFactor = Math.max(0.75f, 1 - Math.abs(position - 0.125f)); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); } else { page.setAlpha(0); } } } } ``` 使用方式: ```xml <com.example.LoopViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="wrap_content" /> ``` ```java LoopViewPager viewPager = findViewById(R.id.view_pager); PagerAdapter adapter = new MyPagerAdapter(); viewPager.setAdapter(adapter); viewPager.setInterval(3000); viewPager.startAutoScroll(); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值