Android广告位循环轮播图的实现
2016-07-14 11:21
239 查看
这几天想要实现一个广告位的循环轮播图,遇到了一些问题,现在已经成功解决了,所以还是想分享一下。
首先,循环轮播图是通过定时切换ViewPager页实现的,但是如果按照常规的viewpager实现,则会遇到以下几个问题:
1. 刚一打开界面的时候,ViewPager是不能向左滑动的。
2.当从最后一页(假设只有四页)切换回第一页时,在视觉上会快速的向左划过第三页、第二页,最后回到第一页(这显然不是我们想看到的效果)。
下面我们来具体实现一下(需要注意的地方我就在代码中注释了):
①首先是xml文件
②Adapter部分
③代码实现部分
如此便大功告成了,以上代码可直接拷贝运行看效果(图片什么的自己放吧)。
首先,循环轮播图是通过定时切换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) { } }
如此便大功告成了,以上代码可直接拷贝运行看效果(图片什么的自己放吧)。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories