轮播图是很常用的一个效果 核心功能已经实现 没有什么特殊需求 自己没事研究的 所以封装的不太好 一些地方还比较糙 为想要研究轮播图的同学提供个参考

目前测试图片为mipmap中的图片 没有写从网络加载图片 可自行根据需求在getShowView()方法中修改

1.定时切换

通过handle延时发送通知改变界面 然后在切换viewpage的界面之后 再次发送此延时通知 就ok咯 还可以通过timer定时器实现

2.无限轮播效果

如果我们只是在自动轮播到最后一页 然后进行判断让切换到第一页 这样是可以实现轮播的效果

但是 有两个问题

  1. 切换从最后一页切换到第一页的时候有一个很明显的回滚效果 不是我们想要的
  2. 当我们手动滑动的时候 在第一页和最后一页的时候 无法继续左右滑动 因为已经没有下一页了

先看张图(偷来的)

不得不说这位兄弟的图p的很形象 简直完美

虽然看到的是三张图 实际上是五张 数据多的时候也按照这种方式添加数据 当view4的时候自动切换到view5时 进行判断让到切换到view2 这样造成的感觉就是最后一张下来是第一张

我们利用viewpage自带的方法切换界面立即切换没有滚动效果 当图片一样的时候是看不出图片变化的

setCurrentItem(int item, boolean smoothScroll)

第二个参数设置false 界面切换的时候无滚动效果 默认true

好啦 接下来看代码

public class BannerViewPager extends FrameLayout {

    private ViewPager viewPager;
private TextView tvTitle;
private LinearLayout indicatorGroup;
private BannerAdapter adapter;
private List<String> titles;//标题集合
private List imageUrls;//图片数据
private List<View> views;//轮播图显示
private ImageView [] tips;//保存显示的小圆点
private int count;//保存imageUrls的总数
private int bannerTime=2500;//轮播图的间隔时间
private int currentItem=0;//轮播图的当前选中项
private long releaseTime = 0;//保存触发时手动滑动的时间 进行判断防止滑动之后立即轮播
private final int START=10;
private final int STOP=20;
private Context context;
private Handler handler; private final Runnable runnable=new Runnable() {
@Override
public void run() {
long now=System.currentTimeMillis();
if (now-releaseTime>bannerTime-500){
handler.sendEmptyMessage(START);
}else{
handler.sendEmptyMessage(STOP);
}
}
}; public BannerViewPager(Context context) {
super(context);
} public BannerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
titles=new ArrayList<>();
titles.add("标题1");
titles.add("标题2");
titles.add("标题3");
imageUrls=new ArrayList();
views=new ArrayList<>();
init(context,attrs);
} private void init(final Context context, AttributeSet attrs){
View view= LayoutInflater.from(context).inflate(R.layout.layout_banner,this);
viewPager= (ViewPager) view.findViewById(R.id.banner_view_pager);
tvTitle= (TextView) view.findViewById(R.id.banner_title);
indicatorGroup= (LinearLayout) view.findViewById(R.id.banner_indicator);
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case START:
viewPager.setCurrentItem(currentItem+1);
handler.removeCallbacks(runnable);
handler.postDelayed(runnable,bannerTime);
break;
case STOP:
releaseTime=0;
handler.removeCallbacks(runnable);
handler.postDelayed(runnable,bannerTime);
break;
}
}
};
} /**
* 初始化数据 以及拿到数据后的各种设置
* 可以是网络地址 也可是项目图片数据
* @param imageUrls
*/
public void setData(List<?> imageUrls){
this.imageUrls.clear();
this.count=imageUrls.size();
this.imageUrls.add(imageUrls.get(count-1));
this.imageUrls.addAll(imageUrls);
this.imageUrls.add(imageUrls.get(0)); initIndicator();
getShowView();
setUI();
} /**
* 设置标题
* @param titles
*/
public void setTitles(List<String> titles){
this.titles.clear();
this.titles.addAll(titles);
}
/**
* 设置小圆点指示器
*/
private void initIndicator(){
tips=new ImageView[count];
LinearLayout.LayoutParams layoutParams = new LinearLayout.
LayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
layoutParams.height=10;
layoutParams.width=10;
layoutParams.leftMargin = 5;// 设置点点点view的左边距
layoutParams.rightMargin = 5;// 设置点点点view的右边距
for (int i=0;i<count;i++){
ImageView imageView=new ImageView(context);
if (i == 0) {
imageView.setBackgroundResource(R.drawable.shape_circle_red);
} else {
imageView.setBackgroundResource(R.drawable.shape_circle_white);
} tips[i] = imageView;
indicatorGroup.addView(imageView, layoutParams);
}
} /**
* 获取显示图片view
*/
private void getShowView(){
for (int i=0;i<imageUrls.size();i++){
ImageView imageView=new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
if (imageUrls.get(i) instanceof String){ }else{
imageView.setImageResource((Integer) imageUrls.get(i));
}
views.add(imageView);
}
} /**
* 设置UI
*/
private void setUI(){
adapter=new BannerAdapter();
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(onPageChangeLis);
viewPager.setCurrentItem(1);
handler.postDelayed(runnable,bannerTime);
} /**
* viewPage改变监听
*/
private ViewPager.OnPageChangeListener onPageChangeLis=new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
//计算当前页的下标
int max = views.size() - 1;
int temp = position;
currentItem = position;
if (position == 0) {
currentItem = max - 1;
} else if (position == max) {
currentItem = 1;
}
temp = currentItem - 1;
setIndicatorAndTitle(temp);
} @Override
public void onPageScrollStateChanged(int state) {
currentItem=viewPager.getCurrentItem();
switch (state) {
case 0:
//Log.e("aaa","=====静止状态======");
if (currentItem == 0) {
viewPager.setCurrentItem(count, false);
} else if (currentItem == count + 1) {
viewPager.setCurrentItem(1, false);
}
break;
case 1:
// Log.e("aaa","=======手动拖拽滑动时调用====");
releaseTime = System.currentTimeMillis();
if (currentItem == count + 1) {
viewPager.setCurrentItem(1, false);
} else if (currentItem == 0) {
viewPager.setCurrentItem(count, false);
}
break;
case 2:
// Log.e("aaa","=======自动滑动时调用====");
break;
}
}
}; /**
* 设置指示器和标题切换
* @param position
*/
private void setIndicatorAndTitle(int position){
tvTitle.setText(titles.get(position)); for (int i=0;i<tips.length;i++){
if (i==position){
tips[i].setBackgroundResource(R.drawable.shape_circle_red);
}else{
tips[i].setBackgroundResource(R.drawable.shape_circle_white);
}
}
} /**
* 适配器
*/
class BannerAdapter extends PagerAdapter{
@Override
public int getCount() {
return views.size();
} @Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(views.get(position));
return views.get(position);
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}

Activity代码

BannerViewPager banner= (BannerViewPager) findViewById(R.id.banner);
List<Integer> imageUrl=new ArrayList<>();
imageUrl.add(R.mipmap.aiyo);
imageUrl.add(R.mipmap.dipang1);
imageUrl.add(R.mipmap.ic_launcher);
banner.setData(imageUrl);
最后提供两个github上大神封装好的轮播图

建议不太会的同学先搞清楚基本的逻辑在使用第三方库

https://github.com/youth5201314/banner

https://github.com/bingoogolapple/BGABanner-Android

android 轮播图的更多相关文章

  1. Android 轮播图Banner切换图片的效果

    Android XBanner使用详解 2018年03月14日 08:19:59 AND_Devil 阅读数:910   版权声明:本文为博主原创文章,未经博主允许不得转载. https://www. ...

  2. 029 Android 轮播图广告Banner开源框架使用

    1.Banner介绍 现在的绝大数app都有banner界面,实现循环播放多个广告图片和手动滑动循环等功能. 2.使用环境配置(具体可见github开源项目) (1)添加依赖 在build.gradl ...

  3. Android轮播图

    轮播图是很常用的一个效果 核心功能已经实现 没有什么特殊需求 自己没事研究的 所以封装的不太好 一些地方还比较糙 为想要研究轮播图的同学提供个参考目前测试图片为mipmap中的图片 没有写从网络加载图 ...

  4. android轮播图的实现原理

    1.轮播图的点:RadioGroup,根据网络请求的数据,解析得到的图片的个数,设置RadioGroup的RadioButton的个数. 2.轮播图的核心技术:用Gallery来存放图片,设置适配器. ...

  5. Android轮播图Banner的实现

    从慕课网上学了一门叫做“不一样的自定义实现轮播图效果”的课程,感觉实用性较强,而且循序渐进,很适合初学者.在此对该课程做一个小小的笔记. 实现轮播思路: 1.一般轮播图是由一组图片和底部轮播圆点组成, ...

  6. [android] 轮播图-滑动图片标题焦点

    谷歌提供的v4包,ViewPager 在布局文件中,先添加<android.support.v4.view.ViewPager/>控件,这个只是轮播的区域 在布局文件中,布置标题描述部分 ...

  7. [android] 轮播图-无限循环

    实现无限循环 在getCount()方法中,返回一个很大的值,Integer.MAX_VALUE 在instantiateItem()方法中,获取当前View的索引时,进行取于操作,传递进来的int ...

  8. 自定义完美的ViewPager 真正无限循环的轮播图

    网上80%的思路关于Android轮播图无限循环都是不正确的,不是真正意义上的无限循环, 其思路大多是将ViewPager的getCount方法返回值设置为Integer.MAX_VALUE, 然后呢 ...

  9. Android自定义控件之轮播图控件

    背景 最近要做一个轮播图的效果,网上看了几篇文章,基本上都能找到实现,效果还挺不错,但是在写的时候感觉每次都要单独去重新在Activity里写一堆代码.于是自己封装了一下.本篇轮播图实现原理原文出处: ...

随机推荐

  1. EnterpriseLibrary 6.0(微软企业库6.0学习笔记) 之Data Access Block 配置和获取链接字符串

    EnterpriseLibrary 的特点是快速开发,融合了微软工程师多年的经验,现在在微软内部有专门的一个小组在完善EnterpriseLibray,最近的更新时间是April 2013. 相关链接 ...

  2. 深入浅出SQL注入

    原文:深入浅出SQL注入 之前在做学生信息管理系统和机房收费系统的时候,对于SQL注入的问题已经是司空见惯,但是并没有真正的地形象生动的理解SQL注入到底是什么玩意儿.直到这次做牛腩才在牛老师的举例之 ...

  3. 【转】Android 工程在4.0基础上混淆

    Android现在对安全方面要求比较高了,我今天要做的对apk进行混淆,用所有的第三方工具都不能反编译,作者的知识产权得到保障了,是不是碉堡了.   一,首先说明我这是在4.0基础上进行的.   先看 ...

  4. C# socket通信随记回顾

    ----tcp(传输 控制 协议)是可靠消息:三次握手(发给对方,对方发给自己,证明对方接到消息,在发给对方,说明自己能接到对方消息,这样就都知道了):tcp:每发送一次消息,对方都会回复,证明接受到 ...

  5. iOS后向兼容:如何发现过期接口

    以4.3以下兼容性为例,在项目预编译头文件(xx.pch)中加入如下代码: #import <Availability.h> #define __AVAILABILITY_INTERNAL ...

  6. 微信SDK使用总结

    最近做一个分享功能,需要使用微信SDK分享内容给朋友或朋友圈.期间遇到些奇怪的问题,花了点时间去折腾了一番. 首先需要到微信开放平台http://open.weixin.qq.com/?lang=zh ...

  7. maven 启蒙

    Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具.为了替代ANT的Apache开源项目.现在的项目越来越大.ANT已经不适用了. 1.部署m ...

  8. iOS基础 - UIDynamic

    一.UIKit动力学 UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit 注意:UIKit动力学的引入,并不是 ...

  9. HTML5 CANVAS制图 基础总结

    一.基本绘图 首先,定义2D渲染变量ct(这里用了Jquery库): var ct = $(#canvasId).get(0).getContext('2d'); 以下是绘制各种基本图形的方法: // ...

  10. 【python】初识python的问题

    这两天利用晚上时间简单的了解了一下python语言,在Mac上和Windows上都安装了python,对比两个平台,还是发现在mac上体验比较好一点.安装的版本好像也不一样,语法还有点小区别.简单的对 ...