Android自动轮播的三种方式

方法一:在runable里判断,不是最后条目的时候++,是的话=0,获取当前条目,给viewpager设置,然后在runable里递归post,在外面也post这个run

	// 自动轮播条显示
			if (mHandler == null) {
				mHandler = new Handler() {
					public void handleMessage(android.os.Message msg) {
						int currentItem = mViewPager.getCurrentItem();
						if (currentItem < mTopNewsList.size() - 1) {
							currentItem++;
						} else {
							currentItem = 0;
						}
						mViewPager.setCurrentItem(currentItem);// 切换到下一个页面
// 继续延时3秒发消息,形成循环,可以handleMessage方法里发送消息的
						mHandler.sendEmptyMessageDelayed(0, 3000);
					};
				};
				mHandler.sendEmptyMessageDelayed(0, 3000);// 延时3秒后发消息
			}
....
class TopNewsTouchListener implements OnTouchListener {
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				System.out.println("按下");
// 删除Handler中的所有消息,Callbacks是说有个postDelayed,传的是Runnable,这么这个方法每几秒执行一次
				mHandler.removeCallbacksAndMessages(null);
				// mHandler.postDelayed(new Runnable() {
				//
				// @Override
				// public void run() {
				//
				// }
				// }, 3000);
				break;
			case MotionEvent.ACTION_CANCEL:
//因为当按下没抬起,而是滑了一下,那么事件就取消了,需要重新发送一下
				System.out.println("事件取消");
				mHandler.sendEmptyMessageDelayed(0, 3000);
				break;
			case MotionEvent.ACTION_UP:
				System.out.println("抬起");
				mHandler.sendEmptyMessageDelayed(0, 3000);
				break;
			default:
				break;
			}
			return true;
		}
	}

  方法二:在设置adapter的getposotion方法里返回整数的最大值,写个runable一直然后pager的当前条目++,然后递归调用post,在外面也post,在外边是第一次调用。在初始化view的时候设置pager的当前条目写个list的整数倍,因为有可能错乱,这样的话在第一页也能向后划了。

	/* 当 holder.setData 才会调用 */
	@Override
	public void refreshView(List<String> datas) {
		this.datas = datas;
		viewPager.setAdapter(new HomeAdapter());
		viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置   Integer.Max_Vlue/2,这样开始位置也能向后划了
		viewPager.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					runTask.stop();   
					break;
// 事件的取消,有可能按下viewpager滑动到listview上停止就不轮播了
				case MotionEvent.ACTION_CANCEL:  
				case MotionEvent.ACTION_UP:
					runTask.start();
					break;
				}
				
				return false; // viewPager 触摸事件 返回值要是false  
			}
		});
		runTask = new AuToRunTask();
		runTask.start();
	}
	boolean flag;
	private AuToRunTask runTask;
//Runnable并不是开启子线程,所以可以在主线程运行,thread才是开启线程
	public class AuToRunTask implements Runnable{
		@Override
		public void run() {
			if(flag){
				UiUtils.cancel(this);  // 取消之前
				int currentItem = viewPager.getCurrentItem();
				currentItem++;
				viewPager.setCurrentItem(currentItem);
				//  延迟执行当前的任务
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public void start(){
			if(!flag){
				UiUtils.cancel(this);  // 取消之前
				flag=true;
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public  void stop(){
			if(flag){
				flag=false;
				UiUtils.cancel(this);
			}
		}
		
	}
	
	class HomeAdapter extends PagerAdapter {
		// 当前viewPager里面有多少个条目
		LinkedList<ImageView> convertView=new LinkedList<ImageView>();
		// ArrayList
		@Override
		public int getCount() {
			return	Integer.MAX_VALUE;//这样写条目就能一直划了
		}
		/* 判断返回的对象和 加载view对象的关系 */
		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}
		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			ImageView view=(ImageView) object;
			convertView.add(view);// 把移除的对象 添加到缓存集合中
			container.removeView(view);
		}
		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			int index=position%datas.size();//访问网络需要这个参数
			ImageView view;
			if(convertView.size()>0){
				view=convertView.remove(0);
			}else{
				view= new ImageView(UiUtils.getContext());
			}
			bitmapUtils.display(view, HttpHelper.URL + "image?name="
					+ datas.get(index));
			container.addView(view); // 加载的view对象
			return view; // 返回的对象
		}
	}

  第三种是用handler发延迟消息,和第二种差不多,第二种是延迟post(runnable),基于2,设置完最大数后可能一直滚动。然后用handler发消息,消息是一直让当前条目++,然后用延迟发消息,在外面也发,这个是第一次发。如果想停下来,定义个变量,在destory里再置为false就行。

	 /*
		  * 自动循环:
		  * 1、定时器:Timer
		  * 2、开子线程 while  true 循环
		  * 3、ColckManager 
		  * 4、 用handler 发送延时信息,实现循环
		  */
		 isRunning = true;
//		 handler.sendEmptyMessageDelayed(0, 2000);
	}
	
	/**
	 * 判断是否自动滚动
	 */
	private boolean isRunning = false;
	
	private Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			
			//让viewPager 滑动到下一页
			viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
			if(isRunning){
				handler.sendEmptyMessageDelayed(0, 2000);
			}
		};
	};
	
	protected void onDestroy() {
		
		isRunning = false;
	};
	private class MyPagerAdapter extends PagerAdapter {
		@Override
		/**
		 * 获得页面的总数
		 */
		public int getCount() {
			return Integer.MAX_VALUE;
		}
		@Override
		/**
		 * 获得相应位置上的view
		 * container  view的容器,其实就是viewpager自身
		 * position 	相应的位置
		 */
		public Object instantiateItem(ViewGroup container, int position) {
			
			System.out.println("instantiateItem  ::"+position);
			
			// 给 container 添加一个view
			container.addView(imageList.get(position%imageList.size()));
			//返回一个和该view相对的object
			return imageList.get(position%imageList.size());
		}
		@Override
		/**
		 * 判断 view和object的对应关系 
		 */
		public boolean isViewFromObject(View view, Object object) {
			if(view == object){
				return true;
			}else{
				return false;
			}
		}
		@Override
		/**
		 * 销毁对应位置上的object
		 */
		public void destroyItem(ViewGroup container, int position, Object object) {
			System.out.println("destroyItem  ::"+position);
			
			container.removeView((View) object);
			object = null;
		}
	}

  当然,不要局限,三种方法可以混着用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张泽旭的专栏

android下拉五级菜单联动

本人是一个不擅长Android的开发的,但是这几天在做联通的一个服务器配件管理系统,做完B/S的又要写C/S的,老板要求没办法。在做的过程中遇到了一个下拉菜单联...

2013
来自专栏上善若水

002android初级篇之ViewPager及PagerSlidingTabStrip listview的使用

listView是一个可以用来显示视图列表的控件。 它使用适配器来为之提供数据和资源。

1283
来自专栏编程之路

羊皮书APP(Android版)开发系列(十)Android开发常用工具类

1361
来自专栏肖蕾的博客

自定义BaseAdapter完美解决ListView异常:java.lang.IllegalStateException这是代码使用方法原理另外

1478
来自专栏水击三千

Android应用开发SharedPreferences存储数据的使用方法

SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的就是一个key-value(键值对)...

3236
来自专栏everhad

ViewPager无限滑动

前言 View轮播效果在app中很常见,一想到左右滑动的效果就很容易想到使用ViewPager来实现。对于像我们常说的banner这样的效果,具备无限滑动的功能...

4017
来自专栏移动端开发

Android学习--RecyclerView

       前面一篇总结了ListView,在这篇我们总结一些这个RecyclerView,我们就从最基本的开始,安卓团队是将RecyclerView定义在s...

23410
来自专栏水击三千

Android学习之简单的数据存储

在Android中,数据存储是开发人员不可以避免的。Android为开发者提供了很多的存储方法,在前面的博客中,已经讲述了sqlite存储数据。今天将介绍用Sh...

2919
来自专栏向治洪

listview动态获取数据

1.主Activity 1 public class MainActivity extends Activity { 2 3 private ...

2309
来自专栏酷玩时刻

Retrofit2+Rxjava+MVP 实践

此博文根据前面两篇文章 Android MVP 架构初试 Android MVP 架构封装 再结合主流框架Retrofit2+Rxjava来个实践(实现聚合网...

3654

扫码关注云+社区

领取腾讯云代金券