android view定时更新,Android 使用viewpager实现无限循环(定时+手动)

博客介绍了Android中ViewPager循环轮播的两种方法,即定时器和手指拨动。详细分析了设置适配器数量为最大值来模拟无限循环的不足,给出了实现左右无限循环的方法,包括适配器代码及页面跳转逻辑,还说明了定时器实现循环轮播的修改代码。

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

循环轮播的方法有两种,一种是使用定时器另外一种是使用手指拨动,相比较而言,定时器实现循环播放比较容易,只要在定时器的消息里加上简单几段代码即可,下面分别就这两种方法给大家详解,具体详情请看下文吧。

int count = adapter.getCount();

if (count > 1) { // 多于1个,才循环

int index = viewPager.getCurrentItem();

index = (index + 1) % count;

viewPager.setCurrentItem(index, true);

}

但如何在手指拨动时,也支持左右无限循环的功能呢?这个问题,我折腾了好久,网上资料多不可用。

比较可笑的是在适配器里,设置数量为最大值;然后,在当前位置为中间的某个值,比如:

public class MyAdapter extends PagerAdapter{

@Override

public int getCount() {

return Integer.MAX_VALUE;

}

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;

}

@Override

public void destroyItem(View container, int position, Object object) {

((ViewPager)container).removeView(mImageViews[position % count]);

}

public Object instantiateItem(View container, int position) {

View view = mImageViews[position % count];

((ViewPager)container).addView(view, 0);

return view;

}

}

protected void onCreate(Bundle savedInstanceState) {

viewPager.setAdapter(new MyAdapter());

//设置ViewPager的默认项, 设置为总数的100倍,一开始才能往左滑动

viewPager.setCurrentItem(count * 100);

}

这种做法,实际上,并没有真正达到左右无限循环;只是一般情况下,很难达到边界(不可滑动)的情况。

通过查阅大量的资料,我发现ViewPager自身并不支持左右无限循环的功能,不得不说,这点真是太失败了。

由于ViewPager自身不支持,我们只能自己找方法了!下面是我实现左右无限循环的方法:

用于显示的mViews,比数据源mList,多了两个节点元素(头节点0:b和尾节点5:e用于跳转)

下图的不带箭头的红线,是mViews根据mList初始化的情况;带箭头的红线是跳转的情况。

具体代码如下:

public class AdapterCycle extends PagerAdapter

implements ViewPager.OnPageChangeListener{

private Context mContext; // 上下文

private LayoutInflater mInflater; // 用于解XML

private LinkedList mViews; // 用于显示的View

private List mList; // 数据源Drawable

private ViewPager mViewPager; //页面

public AdapterCycle(Context context, ViewPager viewPager,

List list)

{

mContext = context;

mInflater = LayoutInflater.from(context);

mViewPager = viewPager;

if (list != null) {

//无论是否多于1个,都要初始化第一个(index:0)

mViews = new LinkedList();

ImageView view = (ImageView) mInflater.inflate(

R.layout.activity_main_item_cycle, null);

Drawable drawable = list.get(list.size() - 1);

view.setImageDrawable(drawable);

mViews.add(view);

//注意,如果不只1个,mViews比mList多两个(头尾各多一个)

//假设:mList为mList[0~N-1], mViews为mViews[0~N+1]

// mViews[0]放mList[N-1], mViews[i]放mList[i-1], mViews[N+1]放mList[0]

// mViews[1~N]用于循环;首位之前的mViews[0]和末尾之后的mViews[N+1]用于跳转

// 首位之前的mViews[0],跳转到末尾(N);末位之后的mViews[N+1],跳转到首位(1)

if( list.size() > 1) { //多于1个要循环

for (Drawable d : list) { //中间的N个(index:1~N)

ImageView v = (ImageView) mInflater.inflate(

R.layout.activity_main_item_cycle, null);

v.setImageDrawable(d);

mViews.add(v);

}

//最后一个(index:N+1)

view = (ImageView) mInflater.inflate(

R.layout.activity_main_item_cycle, null);

drawable = dList.get(0);

view.setImageDrawable(drawable);

mViews.add(view);

}

}

}

@Override

public int getCount() {

return mViews.size();

}

@Override

public boolean isViewFromObject(View view, Object object) {

return view == object;

}

@Override

public void destroyItem(ViewGroup container, int position, Object object) {

((ViewPager) container).removeView(mViews.get(position));

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

View view = mViews.get(position);

container.addView(view);

return view;

}

// 实现ViewPager.OnPageChangeListener接口

@Override

public void onPageSelected(int position) {

LogUtils.logi(TAG, "onPageSelected:" + position);

if ( mViews.size() > 1) { //多于1,才会循环跳转

if ( position < 1) { //首位之前,跳转到末尾(N)

position = mList.size(); //注意这里是mList,而不是mViews

mViewPager.setCurrentItem(position, false);

} else if ( position > mList.size()) { //末位之后,跳转到首位(1)

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

position = 1;

}

}

}

@Override

public void onPageScrolled(int position, float positionOffset,

int positionOffsetPixels) {

// 什么都不干

}

@Override

public void onPageScrollStateChanged(int state) {

// 什么都不干

}

}

//在外层,将mViewPager初始位置设置为1即可

if (mAdapterCycle.getCount() > 1) { //多于1个,才循环并开启定时器

mViewPager.setCurrentItem(1); //将mViewPager初始位置设置为1

startTimer(); //开启定时器,定时切换页面

}

这时,利用定时器,实现循环轮播,需要修改成如下:

int count = adapter.getCount();

if (count > 2) { // 实际上,多于1个,就多于3个

int index = viewPager.getCurrentItem();

index = index % (count - 2) + 1; //这里修改过

viewPager.setCurrentItem(index, true);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值