Android—顶部轮播图

记录:虽然网络上已经有很多很不错三方jar包做顶部轮播图,但是作为一个学习者,还是要了解其中原理,轮子是圆是方,是木头还是橡胶都要自己琢磨一遍。以下记录这次造轮子的相关代码,然后会在项目中删除。
    首先,我想相当于自定义控件,在首布局中引入,名字要写全包名。然后新建一个类来写这个控件,配置相关的xml文件。介绍如下。
首页中引入这个控件,类名为SlideShowView:

 

SlideShowView.java

/**
 * 首页的banner展现,可以手动,自动轮播
 * 
 * @author 作者:Anshay
 * @version 创建时间:2017-6-4
 */
public class SlideShowView extends FrameLayout {

	// 自动轮播启用开关
	private final static boolean isAutoPlay = true;

	// 放轮播图片的ImageView 的list
	private List<ImageView> imageViewsList;

	// 放圆点的View的list
	private List<View> dotViewsList;

	// 翻页控件
	private ViewPager viewPager;

	// 当前轮播页
	private int currentItem = 0;

	// 定时任务
	private ScheduledExecutorService scheduledExecutorService;

	/* 首页banner */
	public static int[] BANNER_IMGS = { R.drawable.banner_01,
			R.drawable.banner_02, R.drawable.banner_03 };

	// Handler
	private Handler handler = new Handler() {
		// 处理反馈的消息
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			viewPager.setCurrentItem(currentItem);// 设置当前页面
		}
	};

	public SlideShowView(Context context) {
		this(context, null);
	}

	public SlideShowView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SlideShowView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initData();
		initUI(context);
		if (isAutoPlay) {
			startPlay();
		}
	}

	/**
	 * 开始轮播图切换
	 */
	private void startPlay() {
		scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
		scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 1, 4,
				TimeUnit.SECONDS);
	}

	/**
	 * 初始化相关数据
	 */
	private void initData() {
		// 实例化两个集合
		imageViewsList = new ArrayList<ImageView>();
		dotViewsList = new ArrayList<View>();
	}

	/**
	 * 初始化Views等UI
	 */
	private void initUI(Context context) {
		LayoutInflater.from(context).inflate(R.layout.layout_slideshow, this,
				true);
		LinearLayout ll = (LinearLayout) findViewById(R.id.dotLayout);
		for (int imageID : BANNER_IMGS) {
			ImageView imgview = new ImageView(context);
			imgview.setImageResource(imageID);
			imgview.setScaleType(ScaleType.FIT_XY);
			imageViewsList.add(imgview);
		}
		dotViewsList.add(findViewById(R.id.v_dot1));
		dotViewsList.add(findViewById(R.id.v_dot2));
		dotViewsList.add(findViewById(R.id.v_dot3));

		viewPager = (ViewPager) findViewById(R.id.viewPager);
		viewPager.setFocusable(true);// 设置可聚焦
		viewPager.setAdapter(new MyPagerAdapter());// 设置适配器
		viewPager.setOnPageChangeListener(new MyPageChangeListener());// 设置监听器
	}

	/**
	 * 填充ViewPager的页面适配器
	 * 
	 * @author Anshay 下午5:02:20
	 */
	private class MyPagerAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return imageViewsList.size();
		}

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

		@Override
		public Object instantiateItem(View container, int position) {
			((ViewPager) container).addView(imageViewsList.get(position));
			return imageViewsList.get(position);
		}

		@Override
		public void destroyItem(View container, int position, Object object) {
			((ViewPager) container).removeView(imageViewsList.get(position));
		}

		@Override
		public void restoreState(Parcelable arg0, ClassLoader arg1) {
		}

		@Override
		public Parcelable saveState() {
			return null;
		}

		@Override
		public void startUpdate(View arg0) {
		}

		@Override
		public void finishUpdate(View arg0) {
		}
	}

	/**
	 * ViewPager的监听器 当ViewPager中页面的状态发生改变时调用
	 * 
	 * @author Anshay 下午5:02:32
	 */
	private class MyPageChangeListener implements OnPageChangeListener {
		boolean isAutoPlay = false;

		@Override
		// 页面正在滑动
		public void onPageScrolled(int arg0, float arg1, int arg2) {
		}

		// 页面滑动状态
		@Override
		public void onPageScrollStateChanged(int arg0) {
			switch (arg0) {
			case 1:// 手势滑动,空闲中
				isAutoPlay = false;
				Log.d("dd", "手势滑动,空闲中");
				break;
			case 2:// 界面切换中
				Log.d("界面切换中", "滑动结束");
				isAutoPlay = true;
				break;
			case 0:// 滑动结束,即切换完毕或者加载完毕
					// 当前为最后一张,此时从右向左滑,则切换到第一张
				Log.d("dd", "滑动结束");
				if (viewPager.getCurrentItem() == viewPager.getAdapter()
						.getCount() - 1 && !isAutoPlay) {
					viewPager.setCurrentItem(0);
				}
				// 当前为第一张,此时从左向右滑,则切换到最后一张
				else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {
					viewPager
							.setCurrentItem(viewPager.getAdapter().getCount() - 1);
				}
				break;
			}
		}

		// 页面被确定选择时
		@Override
		public void onPageSelected(int position) {
			// 设置下方小圆点图片(当前页面的为红色图片,非当前页面的为灰色图片)
			currentItem = position;
			for (int i = 0; i < dotViewsList.size(); i++) {
				if (i == position) {
					((View) dotViewsList.get(position))
							.setBackgroundResource(R.drawable.banner_bar_selected);
				} else {
					((View) dotViewsList.get(i))
							.setBackgroundResource(R.drawable.banner_bar);
				}
			}
		}
	}

	/**
	 * 执行轮播图切换任务
	 */
	private class SlideShowTask implements Runnable {
		@Override
		public void run() {
			synchronized (viewPager) {
				currentItem = (currentItem + 1) % imageViewsList.size();
				// 发送消息给handle去处理(切换viewPager当前视图)
				handler.obtainMessage().sendToTarget();
			}
		}

	}

	/**
	 * 销毁ImageView资源,回收内存
	 */
	private void destoryBitmaps() {

		for (int i = 0; i < BANNER_IMGS.length; i++) {
			ImageView imageView = imageViewsList.get(i);
			Drawable drawable = imageView.getDrawable();
			if (drawable != null) {
				// 解除drawable对view的引用
				drawable.setCallback(null);
			}
		}
	}

}

 

 


layout_slideshow.xml布局

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:id="@+id/dotLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="8dp" >

        <View
            android:id="@+id/v_dot1"
            android:layout_width="8dp"
            android:layout_height="8dp" />

        <View
            android:id="@+id/v_dot2"
            android:layout_width="8dp"
            android:layout_height="8dp"
            android:layout_marginLeft="5dp" />

        <View
            android:id="@+id/v_dot3"
            android:layout_width="8dp"
            android:layout_height="8dp"
            android:layout_marginLeft="5dp" />
    </LinearLayout>

</RelativeLayout>

 

所选的圆点图片

 

 

1   2  3  4

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值