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

Android广告位循环轮播图的实现

2016-07-14 11:21 239 查看
这几天想要实现一个广告位的循环轮播图,遇到了一些问题,现在已经成功解决了,所以还是想分享一下。

首先,循环轮播图是通过定时切换ViewPager页实现的,但是如果按照常规的viewpager实现,则会遇到以下几个问题:

     1. 刚一打开界面的时候,ViewPager是不能向左滑动的。

   2.当从最后一页(假设只有四页)切换回第一页时,在视觉上会快速的向左划过第三页、第二页,最后回到第一页(这显然不是我们想看到的效果)。

下面我们来具体实现一下(需要注意的地方我就在代码中注释了):

①首先是xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context="com.tangao.test.activtiy.LunBoTuActivity">

<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">

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

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:orientation="horizontal">

<ImageView
android:id="@+id/main_tranF_topVP_point1"
android:layout_width="13dp"
android:layout_height="13dp"
android:padding="5dp"
android:background="@drawable/viewpager_point_selected" />

<ImageView
android:id="@+id/main_tranF_topVP_point2"
android:layout_width="13dp"
android:layout_height="13dp"
android:padding="5dp"
android:background="@drawable/viewpager_point" />

<ImageView
android:id="@+id/main_tranF_topVP_point3"
android:layout_width="13dp"
android:layout_height="13dp"
android:padding="5dp"
android:background="@drawable/viewpager_point" />

<ImageView
android:id="@+id/main_tranF_topVP_point4"
android:layout_width="13dp"
android:layout_height="13dp"
android:padding="5dp"
android:background="@drawable/viewpager_point" />
</LinearLayout>

</FrameLayout>

</LinearLayout>


②Adapter部分

public class MyViewPagerAdapter extends PagerAdapter {

private Context context;
private List<ImageView> imageViewList;

public MyViewPagerAdapter(Context context, List<ImageView> imageViewList){
this.context = context;
this.imageViewList = imageViewList;
}

@Override
public int getCount() {
/**
* 这个方法的返回值是ViewPager的页数,不能返回imageViewList.size(),
* 而是应该返回一个很大的值,这里的Integer.MAX_VALUE说明这个viewpager一共有Integer.MAX_VALUE页
* 而这Integer.MAX_VALUE页就是由imageView中的各页 循环排列 而成的,如下:
* 0 1 2 3 0 1 2 3 0 1 2 3 ...
*/

return Integer.MAX_VALUE;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
/**
* position是viewpager的页下标,取值范围为 0~getCount(),
* 所以要想根据position取imageViewList里的东西,必须先取模
*/
int index = position % imageViewList.size();
container.addView(imageViewList.get(index));
return imageViewList.get(index);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
/**
* position须取模,理由同上
*/
container.removeView(imageViewList.get(position % imageViewList.size()));
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}

③代码实现部分

public class LunBoTuActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

private ViewPager mViewPager;
//viewpager显示的原图ID
private int[] imageViewIds = {R.drawable.ic_launcher, R.drawable.qq_round,
R.drawable.weixin_round, R.drawable.weibo_round};
//要显示的viewpager页,图片转换而来的View们
private List<ImageView> imageViewList = new ArrayList<ImageView>();
//viewpager页对应的小圆点(view对象)
private List<ImageView> dots = new ArrayList<ImageView>();

//viewpager当前页的下标,千万别赋值为0!!!否则我们下面使用这个初值后,
//出来的效果就是我们上面说到的第一个问题(不能向左滑)
private int currentDotPosition = 400;//初始值还应该是imageViewList.size()的整数倍

//用作定时触发
private ScheduledExecutorService scheduleExecutorService;
//    android.os中的Handler,注意!
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
System.out.println("Handler!");
super.handleMessage(msg);
mViewPager.setCurrentItem(currentDotPosition);//currentDotPosition取值范围为0~getCount()
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lun_bo_tu);

initValues();
initView();
}

private void initValues() {
//添加要显示的viewpager页(view对象)
for (int i = 0; i < imageViewIds.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(imageViewIds[i]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageViewList.add(imageView);
}

//获取xml中的viewpager小圆点view对象
dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point1));
dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point2));
dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point3));
dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point4));

}

private void initView() {

mViewPager = (ViewPager) findViewById(R.id.main_tranFragment_topViewPager);
mViewPager.setAdapter(new MyViewPagerAdapter(this, imageViewList));//调用一次getCount()
/**
* 这里先要setCurrent一次,否则运行会有问题
* 从这里可以看出,如果我们上面的currentDotPosition设置成0的话,运行后一开始便不能向左滑动
* 如果设置成400,开始运行后就可以向左滑动400次(我还真试过!滑完了之后想,为什么我不先设置成10再试呢)
*/

mViewPager.setCurrentItem(currentDotPosition);//调用一次getCount()
mViewPager.addOnPageChangeListener(this);////调用一
4000
次getCount()
}

@Override
public void onStart() {
/**
* Activity呈现出来的时候,开始计时,触发
*/
scheduleExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduleExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
currentDotPosition = currentDotPosition + 1;
mHandler.obtainMessage().sendToTarget();//通过handler通知主UI更新界面
}
}, 1, 3, TimeUnit.SECONDS);//最开始延时1s,而后每3s触发一次
super.onStart();
}

@Override
public void onStop() {
//Activity消失时,停止计时触发
scheduleExecutorService.shutdown();
super.onStop();

}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

/**
* 监听到页的切换后,改变小圆点的亮度
*
* @param position
*/
@Override
public void onPageSelected(int position) {
//position与setCurrentItem()中的参数相等,且取值都在0~getCount()--(integer.MAX_VALUE);
//改变小圆点亮度
currentDotPosition = position;//用手拨动时,需要给currentDotPosition赋值
for (int i = 0; i < dots.size(); i++) {
if ((position % dots.size()) == i) {
dots.get(i).setBackgroundResource(R.drawable.viewpager_point_selected);
} else {
dots.get(i).setBackgroundResource(R.drawable.viewpager_point);
}
}
}

@Override
public void onPageScrollStateChanged(int state) {

}
}


如此便大功告成了,以上代码可直接拷贝运行看效果(图片什么的自己放吧)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息