您的位置:首页 > 移动开发 > Android开发

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

2016-04-23 17:36 621 查看
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: