Android ViewPager之实现轮播广告效果

相信大多数Android开发者在项目中使用到过ViewPager,其实ViewPager在项目开发中使用 的频率是非常高的,比如:首次打开项目的向导界面以及在轮播图中都会使用到ViewPager,那么本篇博客接下来就是记录使用ViewPager来实现轮播图效果。

注:ViewPager存在于 Android Support V4包中。

本博客是对使用ViewPager实现轮播广告效果的封装,大家在开发中如需使用轮播如功能,可在代码中直接引用我定义的view——AutoShowView便可实现轮播广告的效果,如下: 

<com.znouy.viewpagerdemo.view.AutoShowView
        android:id="@+id/asv"
        android:layout_width="match_parent"
        android:layout_height="200dp" >
    </com.znouy.viewpagerdemo.view.AutoShowView>

以下是分析实现过程。

1、在要使用ViewPager自定义view布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <!-- 轮播图 -->
 
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_lunbo"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>
    <!-- 文字描述和点的容器点和容器 -->
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#22000000"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingBottom="5dp"
        android:paddingTop="5dp" >
 
        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第一个点的描述"
            android:textColor="#ffffff" />
 
        <LinearLayout
            android:id="@+id/ll_points"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
        </LinearLayout>
    </LinearLayout>
 
</RelativeLayout>

布局如上,对于点我们在代码中动态添加,但需在xml中定义一个红点和一个白点,白点如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
 
    <corners android:radius="5dp" />
 
    <solid android:color="#ffffff" />
 
</shape>

2、创建VewPager的适配器PagerAdapter的子类PicturePagerAdapter

首先要提供ViewPager数据,即图片数据和点数据,代码如下:

       private void initImageView() {
		for (int i = R.drawable.welcome_1; i < R.drawable.welcome_1 + 4; i++) {
			// 创建ImageView容器
			ImageView imageView = new ImageView(getContext());

			// 设置图片
			imageView.setImageResource(i);
			imageView.setScaleType(ScaleType.FIT_XY);// 图片填充容器
			datas.add(imageView);// 添加到集合中
		}
	}

	private void initPoints() {
		// 因为每次页面改变都会调用该方法,所以进入该方法时先清空集合。
		ll_points.removeAllViews();

		for (int i = 0; i < datas.size(); i++) {
			View view = new View(getContext());
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
					10, 10);
			if (i == selectIndex) {
				tv_desc.setText("图片" + i + "的描述");
				view.setBackgroundResource(R.drawable.point_red);
			} else {
				view.setBackgroundResource(R.drawable.point_white);
			}
			params.leftMargin = 10;
			view.setLayoutParams(params);// 设置布局参数
			ll_points.addView(view);// 添加到点的容器中
		}
	}

接着创建PicturePagerAdapter,将数据提供给适配器

public class PicturePagerAdapter extends PagerAdapter {
	private static final String tag = "PicturePagerAdapter";
	List<ImageView> list;

	public PicturePagerAdapter(List<ImageView> imageViews) {
		this.list = imageViews;

	}

	@Override
	public int getCount() {
		// 确定要显示的数据量

		return Integer.MAX_VALUE;// 无限轮播
	}

	@Override
	public boolean isViewFromObject(View view, Object object) {
		// 判断当前要显示的view是否等于标记object,true则显示
		return view == object;
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		position = position % list.size();
		Log.d(tag, "instantiateItem==" + position);
		// 无限轮播-因为position的值从0~Integer.MAX_VALUE
		View view = list.get(position);
		// 添加view到VIewPager中
		container.addView(view);
		return view;

	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		// 从容器中移除view
		Log.d(tag, "destroyItem==" + position);
		container.removeView((View) object);
	}

}

注意上面适配器的代码,为了实现轮播图的无限轮播,就需保证getCount()返回的数据足够大,

       @Override
	public int getCount() {
		// 确定要显示的数据量
		return Integer.MAX_VALUE;// 无限轮播
	}

还有就是当现实到viewpager的最后一张图片,就要调用viewpager控件的setCurrentItem(10000 - 10000 % datas.size())方法将viewpager显示第一张图,代码是在给viewpager设置适配器后,如下: 

vp_lunbo.setAdapter(adapter);
// 设置ViewPager当前选中的位置,会调用instantiateItem,最终会选中item0
// 原理:一个数减去其余数后肯定能被除数整除
vp_lunbo.setCurrentItem(10000 - 10000 % datas.size());

3、实现实现轮播图自动轮播

要实现轮播图自动轮播,首先需创建一个Runnable接口的子类,代码如下:

/** 实现轮播图自动轮播 */

	class AutoScrollTask implements Runnable {

		@Override
		public void run() {
			int currentItem = vp_lunbo.getCurrentItem();
			currentItem++;
			vp_lunbo.setCurrentItem(currentItem);
			start();
		}

		/**
		 * 开始轮播
		 */
		public void start() {
			handler.postDelayed(this, 2000);
		}

		/**
		 * 停止轮播
		 */
		public void stop() {
			handler.removeCallbacks(this);
		}
	}

然后再给viewpager设置触摸监听器,实现触摸停止轮播,松开又可以自动轮播了

// viewpager 注册触摸事件监听器,实现自动轮播
vp_lunbo.setOnTouchListener(new OnTouchListener() {

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:// 按下停止轮播
			autoScrollTask.stop();
			break;
		case MotionEvent.ACTION_MOVE:

			break;
		case MotionEvent.ACTION_UP:// 松开,取消 开始轮播
		case MotionEvent.ACTION_CANCEL:
			autoScrollTask.start();
			break;

		default:
			break;
		}
		return false;// 不会影响其他view的事件分发
	}
});

4如何使用自定义的轮播图视图View

只需在需要使用该轮播图视图Viewactivity中进行布局即可,如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
 
    <com.znouy.viewpagerdemo.view.AutoShowView
        android:id="@+id/asv"
        android:layout_width="match_parent"
        android:layout_height="200dp" >
    </com.znouy.viewpagerdemo.view.AutoShowView>
 
</RelativeLayout>

这样在以后开发中,如需使用轮播图效果,直接在activity多对应的布局引用即可,是不是极大的减轻你开发的工作量了。

以上只是部分代码,有兴趣的请点击此处下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值