简单实现android轮播图

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

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

1.定时切换

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义控件实现简单的轮播图控件

    最近要做一个轮播图的效果,网上看了几篇文章,基本上都能找到实现,效果还挺不错,但是在写的时候感觉每次都要单独去重新在Activity里写一堆代码.于是自己封装了一下.本篇轮播图实现原理原文出处:循环广告位组件的实现,这里只是做了下封装成一个控件,不必每次重复写代码了. 效果图: 实现分析 轮播图的功能就是实现左右滑动的广告.图片信息展示,那我们就用ViewPager来实现,由于考虑到用户体验,我们还需要在下面加一个指示器来标示滑动到了第几张轮播图.指示器我们可以用一个线性布局来根据要展示的轮播图

  • Android仿一号店货物详情轮播图动画效果

    还不是很完全,目前只能点中间图片才能位移,图片外的其他区域没有..(属性动画),对了,图片加载用得是facebook的一款android图片加载库,感觉非常NB啊,完爆一切. 1.先看布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t

  • Android自定义控件实现优雅的广告轮播图

    前言 今天给大家带来一个新的控件–轮播图,网上已经有很多这类的博客来讲解如何实现的,那么我的这个有哪些特点呢?或是说有哪些不同呢? 满足了轮播图的基本要求,循环滑动,在最后一张切到第一张时可以平稳的过渡 简洁简洁简洁 扩展性强 如何使用 下面我们先展示两种效果图 1 默认效果 代码实现 //布局代码 <com.landptf.view.BannerM android:id="@+id/bm_banner" android:layout_width="match_pare

  • Android实现自定义轮播图片控件示例

    要完成一个轮播图片,首先想到的应该是使用ViewPager来实现.ViewPager已经有了滑动的功能,我们只要让它自己滚动.再加上下方的小圆点就行了.所以我们本次的自定义控件就是由ViewPager和LinearLayout叠加起来组成的. 直接先上效果图: 创建一个自定义的ViewPager 先上完整的代码 package com.kcode.autoscrollviewpager.view; import android.content.Context; import android.os

  • Android下拉刷新与轮播图滑动冲突解决方案

    最近在开发中遇到了这样一个问题,在下拉刷新组件中包含了一个轮播图组件,当左右滑动的图片时很容易触发下拉刷新,如下图所示: 如图中红色箭头所示方向切换轮播图,很容易触发下拉刷新.网上查了很多方法,发现都不能很好的解决,于是自己研究了下. 我选用的第三方控件 1.下拉刷新我选用的是chanven的CommonPullToRefresh(系统自带的SwipeRefreshLayout也应该是一样的道理); 2.轮播图选用的是daimajia的AndroidImageSlider(用ViewPager也

  • Android实现轮播图无限循环效果

    本文实例为大家分享了Android轮播图无限循环的具体代码,供大家参考,具体内容如下 实现无限循环 在getCount()方法中,返回一个很大的值,Integer.MAX_VALUE 在instantiateItem()方法中,获取当前View的索引时,进行取于操作,传递进来的int position是个非常大的数,对他进行求余数 在destroyItem()方法中,同样 在onPageSelected()监听方法中,对传递进来的索引进行取于 反向的无限循环 调用ViewPager对象的setC

  • Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件

    最近用到需要无限轮播自动播放的轮播轮播图,网上感觉都有这样那样的问题,于是自己写了一个通用的控件CarouselFigureView. 特点: 1.可以轮播view可以自己定义,不一定是要是ImageView2.指示器默认显示,但是可以隐藏3.可以设置指示器的颜色.间距.大小 4.有基础的可以自己修改代码改变指示器位置,这个应该不难5.可以自己开启和关闭自动轮播,开启轮播的时候可以设置轮播时间间隔,默认3000毫秒 我们先来看看效果图: 然后来看看使用代码 xml代码 <?xml version

  • Android开发在轮播图片上加入点击事件的方法

    这是我加在里面的代码,用Switch(position) 来获取当前图片,在相应的图片上加入点击事件, case  0:, case 1: 时代码如下,当点击第一张图片时,想实现case 0里面的代码,但是直接直接报错,退出,当点击第二张实现case 1中的代码时却是没问题,我想知道到底哪里不对啊. 对了,这些代码是在Fragemnt内写的,点击图片时是要从一个Fragment转到一个Activity,求大神指教

  • Android中用RxJava和ViewPager实现轮播图

    前言 很多人要实现轮播图都会想到使用ViewPager + Handler来完成轮播图的效果.但是在RxJava快速发展的情况下,已经可以使用RxJava来代替Handler完成这样任务了. 下面我们就来介绍如何实现RxJava+ViewPager的轮播图. 效果图如下 ViewPager的操作 说到ViwePager应该大家都不陌生,它可以结合普通的View也可以结合Fragment一起使用.在此我也就不对它的使用方法进行过多的介绍了.直接开始介绍轮播的方法. 常见的轮播操作 private

  • Android如何使用RecyclerView打造首页轮播图

    先看看效果图: 停在中间自动翻页 序言:最近接到一个任务,做一个类似上面自动翻页的功能.可以看到,这一屏中有三张图片显示出来了,有两张没有显示完全,看到设计图的时候第一反应是可以用viewpager来实现,但是任务却跟你开了一个天大的玩笑,要求是以最左边的图片为基准,也就是说,左边的图片也得显示完全,就像下图所示,后来仔细想想viewpager好像没有这样的功能,也有可能是我不知道,我也没有找到这样的文章或者信息,希望知道的简友私戳交流一下,感激不尽,好了,言归正传 停在左边 在开始之前呢,首先

随机推荐