欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android客户端实现图片轮播控件

程序员文章站 2024-02-26 20:10:16
本文和大家一起写一个android图片轮播控件,供大家参考,具体内容如下 1. 轮播控件的组成部分     我们以知乎日报android客...

本文和大家一起写一个android图片轮播控件,供大家参考,具体内容如下

1. 轮播控件的组成部分

    我们以知乎日报android客户端的轮播控件为例,分析一下轮播控件的主要组成:   

    首先我们要有用来显示图片的view对象,根据上图中底部*的5个点,我们知道需要5个imageview来显示需要轮播的图片,另外还需要5个imageview来显示5个点。现在考虑以下轮播组件应该具有的行为,首先需要每隔一定时间间隔切换到下一张图片,并且图片间切换的效果应该是平滑的,就像“翻书”一样。由此我们可以想到将5个图片当做viewpager的page,这样图片切换时自然会有平滑的效果。接下来,我们还要给底部的5个小点找一个父容器,由于它们是线性排列的,所以用linearlayout是再合适不过了。然后,我们还要把viewpager和容纳5个点的linearlayout放入一个父容器中,这里我们选择使用垂直排列子view的linearlayout。

    这样一来,我们就得到了轮播控件的布局文件(carousel_layout.xml):

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:orientation="vertical">

  <android.support.v4.view.viewpager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

  <linearlayout
    android:id="@+id/dots"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="8dp" >
  </linearlayout>
  
</linearlayout>

    通过对轮播控件的组成部分进行分析,我们已经确定了用什么“数据结构”来表示一个轮播组件,那么接下来,我们要做的就是实现轮播组件的”算法“,也就是业务逻辑。

2. 轮播组件的行为分析

    轮播控件首先要具有的行为是自动播放,也就是每隔一定事件间隔(通常是3到5秒),便自动”翻到下一页“。为了实现这一点,我们可以维护一个currentitem变量来记录当前正在显示的图片,然后设置一个定时任务,调用viewpager的setcurrentitem方法设置当前要显示的图片,并将currentitem设为下一张要显示的图片。有一点需要我们注意的便是播放到最后一张图片时,下一个被显示的应该是第一个图片,而且切换的效果也不再是平滑的。

    轮播控件的还要能响应我们的滑动动作,也就是我们能够通过左右滑动来在不同的图片之间切换,这个行为viewpager自动为我们提供了。另外还有一个轮播控件应该具备的行为是:当切换到指定图片时,相应的圆点应该以区别其他4个圆点的颜色显示,以便用户能够知道当前正在播放的是第几个图片。要实现这一点也不复杂,只需要为viewpager添加一个onpagechangelistener监听器,然后重写相应的回调方法即可,这样当用户选定了某个page时,onpageselected方法会被回调,系统会传入当前page的索引,我们便可以根据这个索引设置相应的圆点颜色。

 3. 轮播控件的具体实现

    经过以上的分析,我们已经清楚的了解了轮播组件的表示及业务逻辑,接下来只要我们用java把这些描述出来就大功告成了。

(1)定时任务
    我们需要定时执行“改变viewpager当前page为下一个page”这一任务,这里我们采用handler来实现,代码如下:

mhandler.postdelayed(task, delay);
  private final runnable task = new runnable() {
    @override
    public void run() {
      if (isautoplay) {
        currentitem = (currentitem + 1) % (mtopstories.size());
        mvp.setcurrentitem(currentitem);
        mhandler.postdelayed(task, delay);
      } else {
        mhandler.postdelayed(task, delay);
      }
    }
  };

    在以上代码中,delay代表我们设置的一个延迟常量(单位ms)。由于我们需要的是循环播放,因此第5张显示完毕后应该显示第一张,所以我们要想第6行那样进行一个模运算,这样currentitem就在0到4之间不停变化了。注意第5行有一个isautoplay变量,这个变量表示当前是否应该自动播放。那么什么时候不应该自动播放呢?我们知道当我们滑动手指切换图片时,图片会“跟随”着我们的手,就好比我们翻书页的时候,只有松开了手书页才能落下。所以我们正在“拖动”图片时,也就是我们的手还没松开时,轮播控件是不应该自动播放的。为了实现这一点,我们只需重写onpagechangelistener中的onpagescrollstatechanged方法,在当前状态为“拖动”时设置isautoplay变量为false。从第10行我们可以知道,当autoplay为false时,不会改变当前显示的图片,仅仅会等过了delay指定的时间后再执行下一次定时任务。 

(2)onpagechangelistener
    上面我们提到了要给viewpager添加一个onpagechangelistener监听器对象,来实现小圆点颜色的改变以及autoplay变量的赋值。具体的实现请看以下代码,代码的含义都很直接:

class toponpagechangelistener implements viewpager.onpagechangelistener {

    @override
    public void onpagescrolled(int position, float positionoffset, int positionoffsetpixels) {

    }

    @override
    public void onpageselected(int position) {
      for (int i = 0; i < mdotsiv.size(); i++) {
        if (i == position) {
          mdotsiv.get(i).setimageresource(r.drawable.dot_focus);
        } else {
          mdotsiv.get(i).setimageresource(r.drawable.dot_blur);
        }
      }
    }

    @override
    public void onpagescrollstatechanged(int state) {
      switch (state) {
        //scroll_state_dragging
        case 1:
          isautoplay = false;
          break;
        //scroll_state_settling
        case 2:
          isautoplay = true;
          break;
        default:
          break;
      }
    }
  }

    在以上代码的第10到16行,我们重写了onpageselected方法,position参数表示当前page的索引。这个方法中,我们设置当前图片对应的圆点图片为dot_focus,设置其他圆点的图片为dot_blur,这样用户就能知道当前的位置。在第21行到32行,我们重写了onpagescrollstatechanged方法,state参数代表了当前的“滚动状态,这个值为1表示当前用户正在”拖动“的过程中,因此要设置isautoplay为false;这个值为2表示用户松开了手,图片正在”滚动“中,这时我们就要把isautoplay设回默认值true,恢复自动播放。

 (3) 更进一步
    有时候我们希望能够从最后一页直接“翻到”第一页,而这种行为默认不被pagerview所支持,要想实现这个行为,我们可以在pagerview中增加一些“辅助页”,并重写onpagechangelisener中的相关方法。然而我们在很多场景中只需要保持pagerview的默认行为就好,要注意增加任何功能都要考虑应用场景,避免画蛇添足。

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