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

目前测试图片为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. Extjs中GridPanel的各个属性与方法

    1.Ext.grid.GridPanel 主要配置项: store:表格的数据集 columns:表格列模式的配置数组,可自动创建ColumnModel列模式 autoExpandColumn:自动充 ...

  2. nginx启动,重启,关闭命令

    nginx启动,重启,关闭命令 停止操作停止操作是通过向nginx进程发送信号(什么是信号请参阅linux文 章)来进行的步骤1:查询nginx主进程号ps -ef | grep nginx在进程列表 ...

  3. Linq to NHibernate入门示例

    Linq to NHibernate入门示例 NHibernate相关: 09-08-25连贯NHibernate正式发布1.0候选版 09-08-17NHibernate中一对一关联的延迟加载 09 ...

  4. Android服务开发经验——优雅地活着

    大多数的Android应用开发都会将注意力集中在界面功能上,只有少数应用会需要一个Service,尤其是一个长期运行的Service,去进行后台联网.环境检测.媒体播放等功能.Android环境下的S ...

  5. SQLSERVER 数据库性能的的基本 MVC + EF + Bootstrap 2 权限管理

    SQLSERVER 数据库性能的基本 很久没有写文章了,在系统正式上线之前,DBA一般都要测试一下服务器的性能 比如你有很多的服务器,有些做web服务器,有些做缓存服务器,有些做文件服务器,有些做数据 ...

  6. FineUI开源版之TreeGrid(修改)

    上篇文章中做了简单实现,但是还是有bug的,还需要在外面写事件的处理,今天又进行修改了. 下面放出代码,同样的  hzh modify标记的就是我进行修改的地方 grid.cs 添加代码 #regio ...

  7. python int异常 python isdigit

    python int是python把任何类型转换成int类型的方法,但是你如果运用不好的话,会引发异常,但是python的str字符串转换方法运用起来倒是比较安全,它把任何对象转换成字符串类型都不会报 ...

  8. @Html.CheckBoxFor为何输出两种控件

    在MVC中当使用@Html.CheckBoxFor时表单上会产生两种控件checkbox和hidden,比如: @Html.CheckBoxFor(model => model.IsTop) 对 ...

  9. [转]在 Mac OS X上编译 libimobiledevice 的方法

    link: http://blog.boceto.fr/2012/05/05/libimobiledevice-for-macosx/ The objective of the day: Compil ...

  10. WCF/WPF公司内部订餐程序开发

    WCF/WPF公司内部订餐程序开发 (服务端篇) 上班的第一天,群里讨论关于订餐的问题,所以想到了要不要自己开发一个公司内部的订餐系统呢?方便公司内部员工的订餐,有了想法就简单的实践了下 . 实现还是 ...