ViewPager可以实现屏幕间的切换,而轮播广告就是不同的视图的切换,由此我们确定程序主体使用ViewPager辅佐其他功能实现广告的轮播。
广告轮播是要实现的是:
1.各个广告图片的不停切换。
2.按手势实现广告图片的切换。
1.按手势实现广告图片的切换
Android自带控件ViewPager就可以实现图片的按手势切换,因此控件使用ViewPager。
2.各个广告图片的不停切换
实现思路:
此次我们使用线程实现图片的定时切换,我们首先定义一个值,这个值代表需要轮播的广告数,然后我们开启一个线程,让线程休息固定的时间(广告轮播的时间)
后,把我们定义的值加1,因为线程不能更新UI界面,所以发送消息出去,消息中传递我们定义的值,在handler中接受该值,让ViewPager设置当前图片为该值对应的图片。
该思路存在一个Bug,就是我们定义的int值是线程不安全的,可能导致我们需要的值发生一些无法预测的错误,因此我们使用线程安全的AtomicInteger来定义该值。
广告轮播的整体思路:
首先定义两个字段,一个boolean字段isContinue用来存是否自动轮播,一个int字段what用来存放当前显示的视图位置(考虑线程安全,用AtomicInteger),ViewPager用来存放需要显示的广告图片;当检测到按下的手势的时候,isContinue置为false,停止自动轮播;检测到放开的手势的时候,isContinue置为true开始轮播。要实现ViewPager的OnPageChangeListener方法,在onPageSelected(int arg0)方法中,把what值置为arg0(what.getAndSet(arg0))。
具体代码如下:
Activity类代码:
public class MainActivity extends Activity {
private ImageView[] imageViews = null;
private ImageView imageView = null;
/**
* viewpager不直接处理每一个视图而是将各个视图与一个键联系起来。这个键用来跟踪且唯一代表一个页面,不仅如此,
* 该键还独立于这个页面所在adapter的位置。当pageradapter将要改变的时候他会调用startUpdate函数,
* 接下来会调用一次或多次的instantiateItem或者destroyItem.
* 最后在更新的后期会调用finishUpdate。当finishUpdate返回时
* instantiateItem返回的对象应该添加到父ViewGroup
* destroyItem返回的对象应该被ViewGroup删除。methodisViewFromObject(View,
* Object)代表了当前的页面是否与给定的键相关联。
*
* 对于非常简单的pageradapter或许你可以选择用page本身作为键,
* 在创建并且添加到viewgroup后instantiateItem方法里返回该page本身即可destroyItem将会将该page从viewgroup里面移除
* 。isViewFromObject方法里面直接可以返回view == object。
* */
private ViewPager advPager = null;
/**
* AtomicInteger,一个提供原子操作的Integer的类。
* 在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。
* 而AtomicInteger则通过一种线程安全的加减操作接口,也就是说当有多个线程操作同一个变量时,
* 使用AtomicInteger不会导致变量出现问题,而且比使用 synchronized效率高
*
* public final int get()//取当前的值
*
* public final int getAndSet(int newValue)//取当前的值,并设置新的值
*
* public final int getAndIncrement()//获取当前的值,并自增
*
* public final int getAndDecrement()//获取当前的值,并自减
*
* public final int getAndAdd(int delta)//获取当前的值,并加上预期的值
*
*
* 初始化值为0
* */
private AtomicInteger what = new AtomicInteger(0);
/**
* 是否自动轮播,手指滑动时,设置为false
* */
private boolean isContinue = true;
private int Time = 3000;// 广告轮播时间
private final Handler viewHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
advPager.setCurrentItem(msg.what);
super.handleMessage(msg);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViewPager();
}
private void initViewPager() {
advPager = (ViewPager) findViewById(R.id.adv_pager);
ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup);
// 这里存放的是三张广告背景
List<View> advPics = new ArrayList<View>();
ImageView img1 = new ImageView(this);
img1.setBackgroundResource(R.drawable.cardetails_img_carbody);
advPics.add(img1);
ImageView img2 = new ImageView(this);
img2.setBackgroundResource(R.drawable.cardetails_img_jiashi);
advPics.add(img2);
ImageView img3 = new ImageView(this);
img3.setBackgroundResource(R.drawable.cardetails_img_xingshi);
advPics.add(img3);
// ViewPager还可以存放视图,代码如下:
// LayoutInflater inflater=getLayoutInflater();
// view1 = inflater.inflate(R.layout.layout1, null);
// view2 = inflater.inflate(R.layout.layout2,null);
// view3 = inflater.inflate(R.layout.layout3, null);
//
// viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
// viewList.add(view1);
// viewList.add(view2);
// viewList.add(view3);
// 对imageviews进行填充,标示每个图片的小圆圈。
imageViews = new ImageView[advPics.size()];
// 小图标
for (int i = 0; i < advPics.size(); i++) {
imageView = new ImageView(this);
imageView.setLayoutParams(new LayoutParams(50, 50));// 图标大小
imageView.setScaleType(ScaleType.FIT_XY);
imageView.setPadding(10, 10, 10, 10);
imageViews[i] = imageView;
if (i == 0) {
imageViews[i]
.setBackgroundResource(R.drawable.feature_point_cur);
} else {
imageViews[i].setBackgroundResource(R.drawable.feature_point);
}
group.addView(imageViews[i]);
}
advPager.setAdapter(new AdvAdapter(advPics));
advPager.setOnPageChangeListener(new GuidePageChangeListener());
advPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
isContinue = false;
break;
case MotionEvent.ACTION_UP:
isContinue = true;
break;
default:
isContinue = true;
break;
}
return false;
}
});
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (isContinue) {
viewHandler.sendEmptyMessage(what.get());
whatOption();
}
}
}
}).start();
}
private void whatOption() {
what.incrementAndGet();// 自增,然后赋值给当前值
// 如果循环超出设置的个数,则设置为开始
if (what.get() > imageViews.length - 1) {
what.getAndAdd(-imageViews.length);
}
try {
Thread.sleep(Time);// 3秒滚动一次
} catch (InterruptedException e) {
}
}
private final class GuidePageChangeListener implements OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
what.getAndSet(arg0);
for (int i = 0; i < imageViews.length; i++) {
imageViews[arg0]
.setBackgroundResource(R.drawable.feature_point_cur);
if (arg0 != i) {
imageViews[i]
.setBackgroundResource(R.drawable.feature_point);
}
}
}
}
}
Adapter适配器代码:
public class AdvAdapter extends PagerAdapter {
private List<View> views = null;
public AdvAdapter(List<View> views) {
this.views = views;
}
// 实现PagerAdapter至少需要实现如下4个方法
/**
* 从当前arg0中删除指定位置(position)的View;
* */
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView(views.get(arg1));
}
/**
* 返回要滑动的VIew的个数
* */
@Override
public int getCount() {
return views.size();
}
/**
* instantiateItem():做了两件事,第一:将当前视图添加到container中,第二:返回当前View
* 第一:将参数里给定的position的视图,增加到conatiner中,供其创建并显示、。
*
* 第二:返回当前position的View做为此视图的Key。
* */
@Override
public Object instantiateItem(View arg0, int arg1) {
((ViewPager) arg0).addView(views.get(arg1), 0);
return views.get(arg1);
}
/**
* 用来判断instantiateItem(ViewGroup,
* int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)
* 返回值:如果对应的是同一个View,返回True,否则返回False。
* */
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- ViewPager是一个控件 -->
<android.support.v4.view.ViewPager
android:id="@+id/adv_pager"
android:layout_width="fill_parent"
android:layout_height="160dp" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/viewGroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="140dp"
android:gravity="center_horizontal"
android:orientation="horizontal" >
</LinearLayout>
</FrameLayout>
</LinearLayout>