在app中图片的轮播显示可以说是非常常见的实现效果了,其实现原理不过是利用ViewPager,然后利用handler每隔一定的时间将ViewPager的currentItem设置为当前item的position+1即可。先来看看效果图吧:

  就是实现这样的一个轮播广告的效果。

  因为这个是自己为了练习仿照某旅游类App做的,所以这里的数据是使用抓包工具抓取的,准备数据等工作就不在这里赘述了,反正数据的添加大体都是相同的。我的思路是这样的,从网络上实时的获取数据(当然你也可以将数据写死),然后通过网络工具类和json解析类完成对数据的解析与封装从List集合。根据集合的长度来决定ViewPager有多少page页面,下面的小圆点有多少。在函数中首先要设置一个boolean类型的标志位,用来判断是否停止轮播的(我们要在此页面不可见(onStop()方法内)的时候结束轮播),定义一个全局变量来记录当前的小圆点的位置。

 private boolean isStop = false;  //标志位,判断是否停止轮播
private int previousPointEnale = 0; //标记上一个小圆点的位置

然后我们就要为ViewPager的轮播做准备了,比如说动态的根据数据条目来生成小圆点,定义适配器等,代码如下:

 /**
* banner的图片轮播事件初始化
*/
private void initCycleEvent() {
//根据解析到的图片的个数,初始化小圆点
LinearLayout.LayoutParams params;
for (int i = 0; i < imageViewList.size(); i++) {
View dot = new View(getActivity());
dot.setBackgroundResource(R.drawable.point_background);
params = new LinearLayout.LayoutParams(15, 15);
params.leftMargin = 10;
dot.setLayoutParams(params);
dot.setEnabled(false);
ll_dot_group.addView(dot);
} //定义匿名适配器
adapter = new PagerAdapter() {
@Override
public int getCount() {
//因为要实现轮播,所以将数值设置的大一些
return Integer.MAX_VALUE;
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public Object instantiateItem(ViewGroup container, final int position) {
imageViewList.get(position % imageViewList.size()).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), WebViewActivity.class);
intent.putExtra("url", bannerList.get(position % imageViewList.size()).getUrl());
startActivity(intent);
}
});
container.addView(imageViewList.get(position % imageViewList.size()));
return imageViewList.get(position % imageViewList.size());
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imageViewList.get(position % imageViewList.size()));
}
};
vp_banner.setAdapter(adapter);
//初始化第一个page页和第一个小圆点
vp_banner.setCurrentItem(0);
ll_dot_group.getChildAt(0).setEnabled(true);
//为viewPager设置监听
vp_banner.addOnPageChangeListener(new MyPageChangeListener());
}

这里小圆点我们没有用图片,而是用自定义的<selector>和<shape>结合来展示出来的。

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/point_bg_enable" android:state_enabled="true"/>
<item android:drawable="@drawable/point_bg_normal" android:state_enabled="false"/>
</selector>

小圆点获取焦点的时候显示的是这个<shape>资源文件:

 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <corners android:radius="3dp" /> <solid android:color="#AAFFFFFF" /> </shape>

失去焦点的时候:

 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <corners android:radius="3dp" /> <solid android:color="#55000000" /> </shape>

适配器PagerAdapter中的getCount()方法,这个方法是返回要展示生成的ViewPager的page页的个数的,instantiateItem()方法(加载page页)的执行次数是根据getCount()的返回值来决定的,所以我们这里因为要"无限"循环,所以将其设置的大一些,使用INTEGER.MAX整数的最大值来表示。imageViewList是存储我们要展示的imageView的集合,正常情况下不需要轮播的时候,我们直接根据position来addView()即可,但是因为要实现轮播,所以我们利用position和imageViewList集合的长度使用求余的方法来确定图片的下标

 position % imageViewList.size()

下面是定义适配器和动态生成标识图片位置的小圆点的代码:

   /**
* banner的图片轮播事件初始化
*/
private void initCycleEvent() {
//根据解析到的图片的个数,初始化小圆点
LinearLayout.LayoutParams params;
for (int i = 0; i < imageViewList.size(); i++) {
View dot = new View(getActivity());
dot.setBackgroundResource(R.drawable.point_background);
params = new LinearLayout.LayoutParams(15, 15);
params.leftMargin = 10;
dot.setLayoutParams(params);
dot.setEnabled(false);
ll_dot_group.addView(dot);
} //定义匿名适配器
adapter = new PagerAdapter() {
@Override
public int getCount() {
//因为要实现轮播,所以将数值设置的大一些
return Integer.MAX_VALUE;
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public Object instantiateItem(ViewGroup container, final int position) {
imageViewList.get(position % imageViewList.size()).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), WebViewActivity.class);
intent.putExtra("url", bannerList.get(position % imageViewList.size()).getUrl());
startActivity(intent);
}
});
container.addView(imageViewList.get(position % imageViewList.size()));
return imageViewList.get(position % imageViewList.size());
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imageViewList.get(position % imageViewList.size()));
}
};
vp_banner.setAdapter(adapter);
//初始化第一个page页和第一个小圆点
vp_banner.setCurrentItem(0);
ll_dot_group.getChildAt(0).setEnabled(true);
//为viewPager设置监听
vp_banner.addOnPageChangeListener(new MyPageChangeListener());
}

记住在addView()和removeView()的时候都是要根据求余的值来找到对应位置的应该展示的imageView。初始化工作完成,下面应该是完成对轮播的操作了,这里我们开启一个线程来每相隔一定的时间,获取当前ViewPager的page页的position,然后+1,再设置当前page页下标为这个新的值即可:

 /**
* 开启轮播线程的方法
*/
private void startBannerScrollThread() {
new Thread(new Runnable() {
@Override
public void run() {
//先判断是否停止轮播
while (!isStop) {
SystemClock.sleep(2000);
handler.post(new Runnable() {
@Override
public void run() {
int newindex = vp_banner.getCurrentItem() + 1;
vp_banner.setCurrentItem(newindex);
}
});
}
}
}).start();
}

当然,因为每个图片展示给我们的时候,在图片下方的指示性小圆点要有相应的变化,所以在ViewPager中我们还要处理它的滑动事件,所以我们自定义了一个类,实现了ViewPager.OnPageChangeListener接口,在onPageSelected()方法中处理相应的事件:

  /**
* viewPager滑动监听事件
*/
class MyPageChangeListener implements ViewPager.OnPageChangeListener { @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
//获取新的一页的位置
int newPosition = position % imageViewList.size();
//将上一个小圆点的背景设为默认那个
ll_dot_group.getChildAt(previousPointEnale).setEnabled(false);
//设置当前page页的小圆点样式
ll_dot_group.getChildAt(newPosition).setEnabled(true);
//把新的位置赋值给previousPointEnale
previousPointEnale = newPosition;
} @Override
public void onPageScrollStateChanged(int state) { }
}

关键的代码和思路就是这样的,这里还有一篇我参照的文章,写的不错,下面把链接放在这里:

ViewPager实现Banner循环播放

ViewPager实现图片的轮播的更多相关文章

  1. ViewPager—02图片无限轮播

    布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...

  2. Android中使用ImageViewSwitcher实现图片切换轮播导航效果

    前面写过了使用ViewFlipper和ViewPager实现屏幕中视图切换的效果(ViewPager未实现轮播)附链接: Android中使用ViewFlipper实现屏幕切换 Android中使用V ...

  3. Android实现广告页图片无限轮播

    一.概述 对于一个联网的Android应用, 首页广告无限轮播基本已经成为标配了. 那么它是怎么实现的呢? 有几种实现方式呢? 二.无限轮播的实现 1.最常规的手段是用 ViewPager来实现 2. ...

  4. iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版)

    这两天使用Reveal工具查看"手机淘宝"App的UI层次时,发现其图片轮播使用了三个UIButton的复用来实现的图片循环无缝滚动.于是乎就有了今天这篇博客,看到“手机淘宝”这个 ...

  5. iOS开发之ImageView复用实现图片无限轮播

    在上篇博客中iOS开发之多图片无缝滚动组件封装与使用给出了图片无限轮播的实现方案之一,下面在给出另一种解决方案.今天博客中要说的就是在ScrollView上贴两个ImageView, 把ImageVi ...

  6. jQuery图片无缝轮播插件;

    图片轮播这种效果在web开发中看常见,网上的插件也有很多,最近在整理项目的过程中,把之前的图片轮播效果整合了一下,整理成一个可调用的插件以做记录,也方便更多前端爱好者来学习使用:图片的轮播原理很简单, ...

  7. WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现

    原文:WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放.图片立体轮播.图片倒影立体滚动)效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...

  8. iOS 两种不同的图片无限轮播

    代码地址如下:http://www.demodashi.com/demo/11608.html 前记 其实想写这个关于无限轮播的记录已经很久很久了,只是没什么时间,这只是一个借口,正如:时间就像海绵, ...

  9. js实现图片无缝轮播

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. 联想打字必须按FN+数字-fn打字

    对于联想G40.14英寸系列的本本,好多时候无意间可能把数字键锁定了. 这时候要做的是:打开运行--输入OSK--打开虚拟屏幕键盘.这时候可以找到 选项---打开数字键盘. 有时候某些电脑上没有NUM ...

  2. javamail+postfix发送邮件

    由于在做项目时,需要用到邮箱服务.但是不想使用163,qq的,所以就自己搭一个邮箱服务器. 在搜索资料发现postfix是个不错的选择,于是就开始配置了. 这是我搜到的最全的的教程了:http://w ...

  3. JDK源码分析之concurrent包(二) -- 线程池ThreadPoolExecutor

    上一篇我们简单描述了Executor框架的结构,本篇正式开始并发包中部分源码的解读. 我们知道,目前主流的商用虚拟机在线程的实现上可能会有所差别.但不管如何实现,在开启和关闭线程时一定会耗费很多CPU ...

  4. AI篇6====>第一讲

    1.人工智能 小米:小爱 百度:AI云平台 科大讯飞AI平台 2.百度语音合成 # Author: studybrother sun from aip import AipSpeech #从文本到声音 ...

  5. <2014 08 29> MATLAB的软件结构与模块、工具箱简示

    MATLAB的系统结构:三个层次.九个部分 ----------------------------------- 一.基础层 是整个系统的基础,核心内容是MATLAB部分. 1.软件主包MATLAB ...

  6. Spring 的IOC容器之XML方式

    1. Spring 入门 1.1 概述 Spring 是一个分层的 JavaEE 轻量级开源框架; Spring 的核心是控制反转(IOC)和面向切面(AOP); 1.2 特点 方便解耦,简化开发; ...

  7. 综合: Java 对象初始化过程

    class Fu { Fu() { show(); } void show() { System.out.println("xixi"); } } class Zi extends ...

  8. plotly简单绘制柱状图

    代码: import plotly.offline as pltoff import plotly.graph_objs as go def bar_charts(name="bar_cha ...

  9. Python列表切片详解([][:][::])

    Python切片是list的一项基本的功能,最近看到了一个程序,里面有这样一句类似的代码: a = list[::10] 1 不太明白两个冒号的意思就上网百度,发现大多数人写的博客中都没有提到这一个用 ...

  10. Python3+Selenium3自动化测试-(一)

    完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱动浏览器做一些基本操作: 窗口尺寸设置.网页截图.刷新.前进和后退 窗口尺寸设置 在测试过程中,我们可能会要求打开浏览 ...