Android ViewFlipper

Overview

用于两个或更多的View之间的切换,在同一时间内只有一个View将被显示。同时我们也可以让其自动切换,根据我们给定的时间间隔,为了不让其切换的效果十分生硬,我们也为为其定义进入动画和退出动画。

常用的方法

  • setFlipInterval 设置每一个View之间切换的时间的间隔
  • setInAnimation 设置View 进入时候的动画
  • setOutAnimation 设置View退出时候的动画
  • startFlipping 开始播放

一个Demo

下面我们将一步步的实现上面的功能

涉及到的知识点

  • 动画(这里使用了补间动画中的 位移动画)
  • Shape-drawable 资源 用来画小圆点
  • 手势,用来监听上一页下一页的操作

用到的素材

  • 9张图片

因为本篇的主要的内容是讲解ViewFlipper,所以第一个页面的GridView控件的使用这里就不在赘述,主要是为了功能的完善加上去的。

使用到的动画

这里使用了4个补间动画-位移动画

  • 从左边进入的动画 对应着手势 向右边滑
  • 从右边退出的动画 对应着手势向右边滑
  • 从右边进入的动画 对应着向左滑
  • 从左边退出的动画 对应着向左滑

Note : 这些动画放在了 res 目录下anim目录中,如果没有此目录需要手动创建,关于动画这里不再赘述,不太了解的可以参考菜鸟教程

left_in.xml 从左边进入的动画 对应着手势 向右边滑 ``

<?xml version="1.0" encoding="utf-8"?>
<!--图片进入的位移动画 从左边向右移动-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="-100%"
    android:toXDelta="0" />

right_out 从右边退出的动画 对应着手势向右边滑

<?xml version="1.0" encoding="utf-8"?>
<!--图片退出的动画,从左边向右边移动-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:toXDelta="100%" />

right_in 从右边进入的动画 对应着向左滑

<?xml version="1.0" encoding="utf-8"?>
<!--图片进入的位移动画 从右边向左移动-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="100%"
    android:toXDelta="0" />

left_out 从左边退出的动画 对应着向左滑

<?xml version="1.0" encoding="utf-8"?>
<!--图片退出的动画 从右边向左边移动-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0%"
    android:toXDelta="-100%" />

shape 小圆点

这些小圆点用来指示图片的进图,一共有两种格式

  • 没有被选中的状态
  • 选中状态

Note: shape xml 文档 放在 drawable 文件夹下

dot_selected 选中状态的小圆点

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <!--填充色-->
    <solid android:color="#8F8F8F" />
    <!--小圆点的边框-->
    <stroke
        android:width="1dp"
        android:color="#000000" />
    <!--小圆点的大小-->
    <size
        android:width="8dp"
        android:height="8dp" />
    <corners android:radius="45dp" />
</shape>

dot_unselected 没有选中的状态

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#FFFFFF" />
    <stroke
        android:width="1dp"
        android:color="#000000" />
    <size
        android:width="8dp"
        android:height="8dp" />
    <corners android:radius="45dp" />
</shape>

代码

为了代码可读性更好一些,将进行分割为几部分

  • 全局变量
  • 初始化代码
  • 手势操作
用到的全部变量
/************
 * 一些全局变量
 ***********/
private ViewFlipper flipper;    //ViewFlipper 对象
private List<Integer> id_list;  //图片Id的集合,为了偷懒在上一个Activity总存储成为了静态
private LinearLayout llDots;   //小点点的父容器
private List<ImageView> dotList; //所有小点点的集合
/***********
 * 手势相关的变量
 ***********/
private GestureDetector detector; //手势监听器
private int currentId; //当前图片的索引
初始化方法
/**
  * 初始化标识图片位置的小圆点
  */
 private void initDots() {
     dotList = new ArrayList<ImageView>();

     //根据图片的数量来设置小圆点的数量
     for (int i = 0; i < id_list.size(); i++) {
         ImageView iv = new ImageView(this);
         //设置包裹内容
         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(-2, -2);
         //设置Margin
         lp.setMargins(3, 3, 3, 3);

         iv.setLayoutParams(lp);
         iv.setImageResource(R.drawable.dot_unselected);
         //添加到dot的父容器中
         llDots.addView(iv);
         dotList.add(iv);
     }
 }

 /**
  * 初始化轮播的视图
  */
 private void initImageView() {
     //根据图片的数量来设置小圆点的数量
     for (int i = 0; i < id_list.size(); i++) {
         ImageView iv = new ImageView(this);
         //设置包裹内容
         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(-1, -1);
         //设置Margin
         iv.setLayoutParams(lp);

         iv.setScaleType(ImageView.ScaleType.FIT_XY);
         iv.setImageResource(id_list.get(i));
         //添加到dot的父容器中
         flipper.addView(iv);
     }
 }

 /**
  * 初始化手势
  */
 private void initGesture() {
     detector = new GestureDetector(this, new MySimpleOnGestureListener());

 }


    @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_album);

     id_list = HomeActivity.ID_List;

     initFindView();
     initDots();
     initImageView();
     initGesture();

     //获取到上一个Activity传递过来的参数
     Intent intent = this.getIntent();
     currentId = intent.getIntExtra("currentId", -1);
   
     //设置当前选中的点
     if (currentId != -1) {
         flipper.setDisplayedChild(currentId);
         dotList.get(currentId).setImageResource(R.drawable.dot_selected);
     }
 }
手势操作的代码
class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
   public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        //滑动距离的绝对值
        int distance = (int) Math.abs(e1.getX() - e2.getX());
        //证明是向左滑动,查看下一个图片
        if (e1.getX() > e2.getX()) {
            if (distance > 300) {
                //设置一下相关的动画
                flipper.setInAnimation(AlbumActivity.this, R.anim.right_in);
                flipper.setOutAnimation(AlbumActivity.this, R.anim.left_out);

                //显示下一个View
                flipper.showNext();

                //将上一个选中的dot取消
                dotList.get(currentId).setImageResource(R.drawable.dot_unselected);
                //计算下一张图片应该选中的小圆点
                currentId = (currentId + 1) == id_list.size() ? 0 : currentId + 1;
                //选中当前的dot
                dotList.get(currentId).setImageResource(R.drawable.dot_selected);
            }
        } else {
            //证明是向右滑动,查看下一个图片
            if (distance > 300) {

                //设置一下相关的动画
                flipper.setInAnimation(AlbumActivity.this, R.anim.left_in);
                flipper.setOutAnimation(AlbumActivity.this, R.anim.right_out);

                //显示上一个视图
                flipper.showPrevious();

                //将上一个选中的dot取消
                dotList.get(currentId).setImageResource(R.drawable.dot_unselected);
                //计算下一张图片应该选中的小圆点
                currentId = (currentId - 1) == -1 ? id_list.size() - 1 : currentId - 1;
                //选中当前的dot
                dotList.get(currentId).setImageResource(R.drawable.dot_selected);
            }
        }
        return true;
    }
}

源码下载

http://git.oschina.net/ShareKnowledge/AndroidViewFlipperDemo

posted @ 2017-08-16 08:54  鲁迅认识的那只猹  阅读(1405)  评论(0编辑  收藏  举报