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