最近实现了使用viewpager实现广告轮播,写个博客给自己记录一下,请各位看官批评指正。
首先,在布局文件中viewpager需要注意的是要把包名写全,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ccffee" />
<LinearLayout
android:id="@+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="5dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:orientation="horizontal" />
</FrameLayout>
</LinearLayout>
线性布局indicator的作用是用来加载广告轮播或者图片浏览时下方的小圆点。
ViewPager中每个view视图的布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical" >
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="100dp"
/>
</LinearLayout>
这里我有一个疑惑,就是图片的大小设置好像并没有什么卵用,加载到viewpager中的视图的大小由viewpager的宽高决定。
在项目中,viewpager要显示的视图的数量一般不是固定的,所以需要我们动态加载视图,代码如下:
for (int i = 0; i < imgs.length; i++) {
View v=LayoutInflater.from(this).inflate(R.layout.item_view, null);
ImageView img=(ImageView)v.findViewById(R.id.img);
img.setBackgroundResource(imgs[i]);
imgList.add(img);
}
图片底部小圆点的数量也需要动态添加,之前在布局中写了一个线性布局用来盛装小圆点的view ,动态加载小圆点代码如下:
// 创建底部指示位置的导航栏
mBottomImages = new ImageView[imgList.size()];
for (int i = 0; i < mBottomImages.length; i++) {
ImageView imageView = new ImageView(this);
//给圆点的view设置宽高,间距等属性
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
80, 80);
params.setMargins(5, 0, 5, 0);
//四个参数分别是左 上 右 下
imageView.setLayoutParams(params);
//初始状态给第一个小圆点设置选中状态
if (i == 0) {
imageView.setBackgroundResource(R.drawable.choosed);
} else {
imageView.setBackgroundResource(R.drawable.unchoose);
}
mBottomImages[i] = imageView;
// 把指示作用的原点图片加入底部的视图中
indicator.addView(mBottomImages[i]);
监听视图滑动的状态:
vp.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
//判断自动轮播到第几张图片,将当前显示的图片的小圆点设为选中的图片
for (int j = 0; j < mBottomImages.length; j++) {
if (arg0 % imgList.size() == j) {
mBottomImages[j].setImageResource(R.drawable.choosed);
} else {
mBottomImages[j].setImageResource(R.drawable.unchoose);
}
}
autoCurrIndex = arg0;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
//ViewPager.SCROLL_STATE_IDLE的状态时表明没有手动的滑动视图,isTouch代表是否在手动滑动的标志 如果用户手动在滑,将这个标志设为true
if(arg0==ViewPager.SCROLL_STATE_IDLE){
isTouch=false;
}else{
isTouch=true;
}
}
});
写一个线程,用来发送空消息给主线程更新界面,实现自动轮播
Thread dt=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//isAuto标志代表是否在自动轮播,可以在activity销毁时将该状态设为 false
while(isAuto){
try {
dt.sleep(4000);
mHandler.sendEmptyMessage(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
在主线程中,写一个内部类 handler
// 定时轮播图片,需要在主线程里面修改 UI
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//如果在手动滑动时,就停止自动轮播,等手动操作停止时,再继续轮播
if(isTouch)
return;
if(!isAuto)
return;
//当前的位置+1
autoCurrIndex++;
vp.setCurrentItem(autoCurrIndex);
break;
}
}
};
在适配器中,需要注意,在instantiateItem方法中需要判断要显示的视图是否有parent,如果有要删掉,否则会抛出异常,因为一个view只能有一个parent,不能被viewgroup重复添加,不要在destroyItem中销毁视图,会出现白屏的情况。
private class MyAdapter extends PagerAdapter {
private List<ImageView> list;
public MyAdapter(List<ImageView> list) {
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
//设置成最大就可以一直向后滑,实现轮播的效果
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
int p = position % list.size();
ImageView view = list.get(p);
// 如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
ViewParent vp = view.getParent();
if (vp != null) {
ViewGroup parent = (ViewGroup) vp;
parent.removeView(view);
}
container.addView(view);
return list.get(p);
}
}
这样广告或图片自动轮播的功能就实现了,资源下载地址请戳:
http://download.csdn.net/detail/u012456602/9685109