简单的轮播图的实现[上]

自己学习 Android 也有一段时间了, 从大二的开学之初开始写 Android 程序,那时候自己真的什么都是不会,除了自己有一些 Java 基础之外,还好,感激当初坚持的自己,自己现在也可以独自写一些 Android 小程序了; 现在,哈哈,还有几天,哦,三天吧,我就是一名大三的学生了,在大三的日子里面,我会比较系统地学习 Android 知识,选择用时间沉淀自己,当然,我会把我学到的知识,整理成博客,毕竟,感觉自己比较喜欢写东西,哈哈…

Android 轮播图在很多的场景,都是可以遇见它们的身影,它们有挺多的特点的:

  • 带有指示器
  • 每一张图带有标题
  • 可以手动向左,或者向右滑动
  • 自动滑动

效果如下图

Peek 2017-08-28 20-10

代码的实现逻辑

1. 在 .xml 文件里面添加布局

这个轮播框在 .xml 文件里面的布局组件还算是挺简单的,我就直接上代码吧,如果您有 Android 基础,应该不难看懂的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.applicationtestbanner.MainActivity">

<FrameLayout
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">



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

<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:background="#39000000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="3dp">

<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"/>

<LinearLayout
android:layout_marginTop="5dp"
android:id="@+id/pointViews"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"/>

</LinearLayout>


</FrameLayout>

</android.support.constraint.ConstraintLayout>

上面,ViewPager 组件主要使用装 img 图片的,而 ViewPager 下面的 android:id=”@+id/linearlayout” 的 LinearLayout 则是用来装标题和指示器的;

下面是布局实现的效果:

布局实现的效果图

2. 在 MainActivity 文件中拿到相应的组件

我们需要拿到 ViewPager 以及灰色的 LieanerLayout 里面的组件,以便于后面对组件填充内容;

这也是直接上代码吧:

1
2
3
4
5
6
7
8
/*
* 初始化组件
* */
public void initView(){
viewPager = (ViewPager) findViewById(R.id.viewPager);//用于填充图片
title = (TextView) findViewById(R.id.content);//用于填充标题
point = (LinearLayout) findViewById(R.id.pointViews);//用于填充指示器原点
}

3. 往空的轮播框里面填充数据

  • 首先准备好三张以上的图片,最好五张吧,数量多,有利于调试得出实验结论; 把准备好的图片放在下面的包路径下面:

    包路径

  • 现在首先需要做的事情,是需要把图片填充并且在 ViewPager 展示出来。需要在 ViewPager 中展示数据,我们就需要继承实现一个 PageAdapter 的抽象类, 在 PagerAdapter 的源码里面介绍到,如果我们实现了这一个类,我们必须实现以下四个重要的方法;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    private class MyAdapter extends PagerAdapter{
    //返回需要显示的 view 个数
    @Override
    public int getCount() {
    return 0;
    }

    //返回 view 复用的规则
    @Override
    public boolean isViewFromObject(View view, Object object) {
    return false;
    }

    //返回需要展示的 view
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    return super.instantiateItem(container, position);
    }

    //销毁已经展示的 view
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    }
    }
    • 第一个 getCount() 方法,在一般的 Adapter 类里面都是可以找到的,它的作用主要是用来获取需要展示在 ViewPager 的 View 的总数;

    • 第二个方法 isViewFromObject(View view, Object object) 比较重要,因为它是返回 view 复用的规则; 要了解这个方法以怎样的方式复用 ViewPager,需要回到它的源码里面:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      /**
      * Determines whether a page View is associated with a specific key object
      * as returned by {@link #instantiateItem(ViewGroup, int)}. This method is
      * required for a PagerAdapter to function properly.
      *
      * @param view Page View to check for association with <code>object</code>
      * @param object Object to check for association with <code>view</code>
      * @return true if <code>view</code> is associated with the key object <code>object</code>
      */
      public abstract boolean isViewFromObject(View view, Object object);

      源码介绍到,方法 isViewFromObject() 是用来确定当前轮播框显示的 Page View 是否与方法 instantiateItem(ViewGroup, int) 返回来的 Object 相同,判断 Page View 与 Object 相同是通过他们自身的一个特殊的 key,当各自的两个 key 相同的时候,就可以在 viewPage 那里显示出对应的 page view了;

    • 第三个方法 instantiateItem(ViewGroup container, int position) 主要的作用是往 ViewGroup 这个容器里面添加 view (需要显示的),以及返回含有 View 的 Object 对象;

    • 第四个方法 destroyItem(ViewGroup container, int position, Object object) 也是比较重要的,它主要的作用是移除 ViewGroup 里面的已经展示过的 View,如果没有即时移除已经展示的 view 的话,会使程序崩溃的; 当 instantiateItem(ViewGroup container, int position) 这个方法放回一个 Object的时候,ViewPager 就是用这个作为 View 用来显示的;

  • 现在需要往 MyAdapter 里面填充用来展示的数据。首先,我们应当拿到图片的资源 ID ,而且把这些图片资源 ID 用来创建用以展示的 ImageView 对象,再然后,把这些 ImageView 对象装载到 List 里面,方便填充到 MyAdapter 里面;代码如下面:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
    * 初始化数据
    */
    public void initData() {
    //获取图片的id
    imageId = new int[]{R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e};

    //把 mImageView 装在 mImageViewList列表里面;
    for (int i = 0; i < imageId.length; i++) {
    mImageView = new ImageView(this);
    mImageView.setBackgroundResource(imageId[i]);

    mImageViewList.add(mImageView);
    }
    }
  • 现在有了数据,就可以往 MyAdpter 里面填充数据了,实现的逻辑如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    private class MyAdapter extends PagerAdapter {

    //返回需要显示的 view 个数
    @Override
    public int getCount() {
    return mImageViewList.size();
    }

    //返回 view 复用的规则
    @Override
    public boolean isViewFromObject(View view, Object object) {
    return view == object;
    }

    //返回需要展示的 view
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    int newPosition = position % mImageViewList.size();
    ImageView imageView = mImageViewList.get(newPosition);
    container.addView(imageView);

    return imageView;
    }

    //销毁已经展示的 view
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
    //Log.d("测试destroyItem里面的 object", "destroyItem: " + object);
    container.removeView((View)object);
    }
    }
  • 然后通过 viewPager 的 setAdapter() 方法把 上面的 MyAdapter 装载在里面:

    1
    2
    3
    4
    5
    6
    /**
    * 配置 viewPager
    */
    public void initMyAdapter(){
    viewPager.setAdapter(new MyAdapter());
    }
  • 通过上面的代码逻辑,我们就可以得到下面的效果图了:
    半成品效果图

总结
目前我们实现了往 ViewPager 里面填充图片了,然后我接下来的博客文章将会带入每一个 View 带有指示器和标题,而且指示器、标题跟随者图片一起运动的效果,感谢各位的阅读…

本文标题:简单的轮播图的实现[上]

文章作者:

发布时间:2017年09月04日 - 11:09

最后更新:2021年06月20日 - 19:06

原始链接:https://hndroid.github.io/2017/09/04/%E7%AE%80%E5%8D%95%E7%9A%84%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%9A%84%E5%AE%9E%E7%8E%B0-%E4%B8%8A/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。