Android使用ViewFlipper实现轮播图

前言

学习安卓的第二周老师要求我们仿写淘宝首页,其中的关键点轮播图浪费了我不少时间.网上的大部分教程都是viewPage或viewPage2,和网页比起来显得十分麻烦.经过不懈努力,终于找到一个控件ViewFlipper以最少的代码来实现轮播图.

ViewFlipper概述

官方文档
ViewFlipper是Android自带的一个多页面管理控件,且可以自动播放! 和ViewPager不同,ViewPager是一页页的,而ViewFlipper则是一层层的,和ViewPager一样,很多时候, 用来实现进入应用后的引导页,或者用于图片轮播。

ViewFlipper初体验

  1. 新建ViewFlipperTest项目
    百科ViewFlipperTest新建项目

  2. 添加图片

    1. 下载图片oneDriver
    2. 复制图片到res/drawable/
  3. 修改activity_main.xml文件

    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
    <?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">

    <ViewFlipper
    android:id="@+id/flipper"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:flipInterval="2000">
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx1"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx2"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx3"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx4"/>
    </ViewFlipper>
    </LinearLayout>
  4. 修改MainActivity.kt文件

    1
    2
    3
    4
    5
    6
    7
    8
    class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val mFilper = findViewById<ViewFlipper>(R.id.flipper)
    mFilper.startFlipping()
    }
    }
  5. 运行效果图
    博客ViewFlipper初体验效果图

给ViewFlipper来点动画

要实现切换动画,需要自定义xml动画文件

  1. 新建res/anim文件夹
  2. 编写右边进入滚动动画right_in.xml
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="1500"
    android:fromXDelta="100%p"
    android:toXDelta="0" />
    </set>
  3. 编写右边退出滚动动画right_in.xml
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="1500"
    android:fromXDelta="0"
    android:toXDelta="-100%p" />
    </set>
  4. activity_main.xml文件中引用
    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
    <?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">

    <ViewFlipper




    android:inAnimation="@anim/right_in"
    android:outAnimation="@anim/right_out"



    android:id="@+id/flipper"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:flipInterval="2000">
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx1"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx2"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx3"/>
    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/tx4"/>
    </ViewFlipper>
    </LinearLayout>
  5. 效果
    博客ViewFlipper初体验加入动画效果图2

让ViewFlipper支持手势

  1. 在anim下新增left_in.xml文件,让其支持左滑动动画
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="500"
    android:fromXDelta="-100%p"
    android:toXDelta="0" />
    </set>
  2. 在anim下新增left_out.xml文件,让其支持左滑动动画
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="500"
    android:fromXDelta="0"
    android:toXDelta="100%p" />
    </set>
  3. 新建MyGestureListener.kt文件,添加如下代码:
    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
    // 继承手势检测器
    class MyGestureListener(private val myFilper:ViewFlipper,private val context: Context) : GestureDetector.SimpleOnGestureListener(){
    private val MIN_MOVE = 200; //最小距离
    //OnFling中根据X轴方向移动的距离和速度来判断当前用户是向左滑还是向右滑,
    // 从而利用showPrevious()或者showNext()来显示上一张或者下一张图片
    override fun onFling(
    e1: MotionEvent?,
    e2: MotionEvent?,
    velocityX: Float,
    velocityY: Float
    ): Boolean {
    if (e1!=null&&e2!=null){
    if(e1.x-e2.x>MIN_MOVE){
    myFilper.setInAnimation(context,R.anim.right_in)
    myFilper.setOutAnimation(context,R.anim.right_out)
    myFilper.showNext()
    }else if (e2.x - e1.x > MIN_MOVE){
    myFilper.setInAnimation(context,R.anim.left_in)
    myFilper.setOutAnimation(context,R.anim.left_out)
    myFilper.showPrevious()
    }
    // 停止自动轮播
    myFilper.stopFlipping()
    // 3秒延时器
    Timer().schedule(3000){
    // 开始自动播放
    myFilper.startFlipping()
    }
    }
    return true
    }
    }
  4. 应用检测器,修改MainActivity.kt文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class MainActivity : AppCompatActivity() {
    private lateinit var mDetector: GestureDetector
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    // 实例化viewFlipper
    val mFilper = findViewById<ViewFlipper>(R.id.flipper)
    // 实例化手势监听器
    var mMyGestureListener = MyGestureListener(mFilper,applicationContext)
    // 应用监听器
    mDetector = GestureDetector(this,mMyGestureListener)
    // 开始播放
    mFilper.startFlipping()
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
    return mDetector.onTouchEvent(event)
    }
    }
  5. 效果图,有点BUG但是懒得修
    博客ViewFlipper初体验手势体验

    本篇代码

    Github


Android使用ViewFlipper实现轮播图
https://007666.xyz/2022/10/16/Android使用ViewpFilper实现轮播图/
作者
梦无念
发布于
2022年10月16日
许可协议
CC BY-NC-SA 4.0