Android学习(40) -- 自定义控件(4)广告轮播(ViewPager)

ViewPager是3.0之后才出现的,之前版本使用v4包

ViewPager预加载机制:最多保存3个page,超过的将需要使用destroyItem被销毁掉

效果图片


1、在layout布局文件中定义布局

<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" >

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewPager"
        android:background="#77000000"
        android:orientation="vertical"
        android:padding="8dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="我是文本"
            android:textColor="#ffffff"
            android:textSize="14sp" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

2、在Java代码中创建ViewPager对象 并添加适配器

在PagerAdapter中我们要明白什么是预加载机制
a、当滑动图片的时候,存在对滑动的View 和 将要进来的View的判断是否是同一个 true: 表示不去创建,使用缓存 false:去重新创建 view
b、ViewPager预加载机制:最多保存3个page,超过的将需要使用destroyItem被销毁掉
注意:要去掉destroyItem中调用父类中的方法,因为该方法中只存在一个异常 并建议子类重写。

还有要自己重写instantiateItem 和 destroyItem方法

</pre><pre name="code" class="html">public class MainActivity extends Activity {

	private ViewPager viewPage;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		initView();

		initData();
	}

	/**
	 * 初始化View
	 */
	private void initView() {
		setContentView(R.layout.activity_main);
		viewPage = (ViewPager) findViewById(R.id.viewPager);

	}

	/**
	 * 初始化数据
	 */
	private void initData() {

		// 绑定Adapter
		viewPage.setAdapter(new MyPagerAdapter());
	}

	private class MyPagerAdapter extends PagerAdapter {

		/**
		 * 返回多少页
		 */
		@Override
		public int getCount() {
			return 0;
		}

		/**
		 * 判断当前滑动的View 和 将要进来的View是否是同一个 true: 表示不去创建,使用缓存 false:去重新创建 view:
		 * 当前滑动的view object:将要进入的新创建的view,由instantiateItem方法创建
		 */
		@Override
		public boolean isViewFromObject(View view, Object object) {
			return view == object;
		}

		/**
		 * 类似于BaseAdapger的getView方法 用了将数据设置给view 由于它最多就3个界面,不需要viewHolder
		 */
		@Override
		public Object instantiateItem(ViewGroup container, int position) {

			return super.instantiateItem(container, position);
		}

		/**
		 * 销毁page position: 当前需要消耗第几个page object:当前需要消耗的page
		 */
		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			// super.destroyItem(container, position, object); 要注释掉
			container.removeView((View) object);
		}

	}

}


3、创建数据

3.1 创建一个Ad类用于封装数据

public class Ad {

	private int resId;
	private String intro;

	public Ad(int resId, String intro) {
		super();
		this.resId = resId;
		this.intro = intro;
	}

	public String getIntro() {
		return intro;
	}

	public void setIntro(String intro) {
		this.intro = intro;
	}

	public int getResId() {
		return resId;
	}

	public void setResId(int resId) {
		this.resId = resId;
	}
}

3.2、在java中创建List 并封装数据

private ArrayList<Ad> list = new ArrayList<Ad>();

	private void initData() {
		list.add(new Ad(R.drawable.a, "不低俗,不能低俗"));
		list.add(new Ad(R.drawable.b, "回来了,再唱经典老歌引百万人同唱啊"));
		list.add(new Ad(R.drawable.c, "电影如何升级"));
		list.add(new Ad(R.drawable.d, "TV版大放送"));
		list.add(new Ad(R.drawable.e, "热血的反杀"));
		
		//绑定Adapter
		viewPage.setAdapter(new MyPagerAdapter());
	}


4、完善PagerAdapter操作

1、确定数据的总的数量

2、将数据添加到ImageView中

3、将View添加到ViewPager中 并将View返回

	private class MyPagerAdapter extends PagerAdapter{

		/**
		 * 返回多少页
		 */
		@Override
		public int getCount() {
			return list.size();
		}
		/**
		 * 判断当前滑动的View 和 将要进来的View是否是同一个
		 * true: 表示不去创建,使用缓存  false:去重新创建
		 * view: 当前滑动的view
		 * object:将要进入的新创建的view,由instantiateItem方法创建
		 */
		@Override
		public boolean isViewFromObject(View view, Object object) {
			return view == object;
		}

		/**
		 * 类似于BaseAdapger的getView方法
		 * 用了将数据设置给view
		 * 由于它最多就3个界面,不需要viewHolder
		 */
		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			//将广告布局添加进来
			View view = View.inflate(MainActivity.this, R.layout.adapter_ad, null);
			
			//获取到布局中ImageView 
			ImageView imageView = (ImageView) view.findViewById(R.id.img);
			
			//获取到集合中指定的AD数据
			Ad ad = list.get(position);
			//将图片设置到ImageView上
			imageView.setImageResource(ad.getResId());
			
			//一定不能少,将view加入到viewPager中
			container.addView(view);
			
			return view;
		}
		/**
		 * 销毁page
		 * position: 当前需要消耗第几个page
		 * object:当前需要消耗的page
		 */
		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			//super.destroyItem(container, position, object);  要注释掉
			container.removeView((View)object);
		}
		
		
	}
	
}

5、我们此时就可以显示图片数据了

6、将文本进行显示

1、创建TextView对象

2、使用viewPage的OnPageChangeListener监听获取到ViewPager滑动时候获取当前是第几页

	/**
	 * ViewPager监听
	 */
	private void initListener() {
		viewPage.setOnPageChangeListener(new OnPageChangeListener() {
			
			@Override
			/*
			 * 此方法是页面跳转完后得到调用,
			 * position是你当前选中的页面的position(位置编号)
			 */
			public void onPageSelected(int position) {
				updateIntroAndDot();
			}
			
			@Override
			/*
			 * 当页面在滑动的时候会调用此方法,在滑动被停止之前,此方法回一直得到调用。
			 * 其中三个参数的含义分别为:
			 * position :当前页面,及你点击滑动的页面
			 * positionOffset:当前页面偏移的百分比
			 * positionOffsetPixels:当前页面偏移的像素位置  
			 * 
			 */
			public void onPageScrolled(int position, float positionOffset,
					int positionOffsetPixels) {
			}
			
			@Override
			/*
			 *  此方法是在状态改变的时候调用,其中state这个参数有三种状态(0,1,2)。
			 *  state ==1的时辰默示正在滑动,
			 *  state==2的时辰默示滑动完毕了,
			 *  state==0的时辰默示什么都没做。 
			 */
			public void onPageScrollStateChanged(int state) {
			}
		});
	}

	/**
	 * 更新文本
	 */
	private void updateIntroAndDot() {
		//获取到当前第几页
		int currentPage = viewPage.getCurrentItem() ;
		//设置文本信息
		tv.setText(list.get(currentPage).getIntro());
	}
	

注意:在初始化数据的时候也要指定获取第一个文本 否则第一次打开的时候会没有数据显示的

tv.setText(list.get(0).getIntro());

布局文件中TextView中要添加如下两个属性

 android:singleLine="true"
android:ellipsize="end"


7、添加图片显示的“点”  页面指示器(小圆点)

1、创建“点”布局
在res下创建一个drawable目录
在drawable目录下创建名称dot_focus.xml的shape文件,用于表现 “小白点”表示选中状态
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval">
    <solid android:color="#ffffff"/>
</shape>

在drawable目录下创建名称dot_unfocus.xml的shape文件,用于表现 “小黑点”表示选中状态
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval">
    <solid android:color="#aa000000"/>
</shape>

为了方便使用,我们创建一个名称为selector_dot.xm l的 selector,用来切换图片
 
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <item android:state_enabled="true" android:drawable="@drawable/dot_focus"></item>
	<item android:drawable="@drawable/dot_unfocus"></item>
</selector>



2、在布局中对应的布局处添加id

3、在java文件中创建对象

4、创建一个初始化“点”的方法(在数据确定数据个数后 创建)

	/**
	 * 初始化“点”方法
	 */
	private void initDot(){
		for (int i = 0; i < list.size(); i++) {
			View view = new View(this);
			//封装了View中宽度和高度
			LayoutParams params = new LayoutParams(8, 8);
			//点和点之间的距离
			if (i != 0) {
				params.leftMargin = 5;
			}
			view.setLayoutParams(params);
			//设置个背景
			view.setBackgroundResource(R.drawable.selector_dot);
			lay_dot.addView(view);
		}
	}

5、在更新文本中处理 点、 文字、 图片的关联,依赖关系

	/**
	 * 更新文本
	 */
	private void updateIntroAndDot() {
		//获取到当前第几页
		int currentPage = viewPage.getCurrentItem() ;
		//设置文本信息
		tv.setText(list.get(currentPage).getIntro());
		
		for (int i = 0; i < lay_dot.getChildCount(); i++) {
			lay_dot.getChildAt(i).setEnabled(i == currentPage);
		}
	}











  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值