Hacks动画篇-Hack1 使用TextSwitcher和ImageSwitcher实现平滑过渡

TextSwitcher和ImageSwitcher

作者:李旺成
时间:2016年5月9日


需求说明

假设,现在要实现一个这样的效果,在 TextView 或者 ImageView 中循环浏览信息。有如下场景:

  • 通过向左和向右的导航按钮浏览日期列表
  • 在日期选择控件中改变日期
  • 倒计时时钟
  • 新闻纲要

(参考自:《Android 50 Hacks》)
要更改 TextView 和 ImageView 的内容非常简单,但是有个缺点,就是直接调用 TextView 或者 ImageView 提供的方法替换内容的时候没有什么视觉效果,显得很单调。

可以看到有不少的 App 在文本内容切换的时候添加了动画效果(如:支付宝)。Android 提供了 TextSwitcher 和 ImageSwitcher 分别替换 TextView 和 ImageView,来实现过渡过程的动画效果。

TextSwitcher 与 ImageSwitcher 简介

老规矩,学习一个控件先看看它的继承结构,这里之所以将 TextSwitcher 与 ImageSwitcher 放在一起介绍,是有原因的,下面会介绍。

继承结构

都是直接继承自 ViewSwitcher(所以就把这”两兄弟“放到一块介绍了),继承结构里面有一个很熟悉的,那就是 FrameLayout(好像哪里都有你…)。看到这里至少可以确认一点,ViewSwitcher 是个容器,从名称上推测,TextSwitcher 应该是 Text(文本)的容器,ImageSwitcher 应该是 Image(图片)的容器。

看看官方文档上是怎么说的

TextSwitcher类

ImageSwitcher类

不是我截错图了,ImageSwitcher 下就是没有简介,那只好看看它的父类了:

ViewSwitcher

介绍都非常简洁(甚至说简单),这里就不纠结了,反正离不了是个容器,直接用起来。

TextSwitcher 简单使用

先看效果:

TextSwitcher演示

1、在布局文件中使用
上面说了,就把它当成普通容器使用即可,示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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">
<Button
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下一个" />
<TextSwitcher
android:id="@+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

2、认识 Factory
文档中提到要给 ViewSwitcher 设置一个 Factory 用来创建 views。来看看这个 Factory 到底是什么:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* Creates views in a ViewSwitcher.
*/

public interface ViewFactory {
/**
* Creates a new {@link android.view.View} to be added in a
* {@link android.widget.ViewSwitcher}.
*
* @return a {@link android.view.View}
*/

View makeView();
}

它是 ViewSwitcher 内部的一个接口,里面只有一个方法,返回值为 View,那么很简单了,只要实现一个方法。

3、为 TextSwitcher 设置 Factory
类似于这种和设置监听有点像的情况,我一般有两种实现方式,一种是让 Activity 实现接口,另一种是使用匿名内部类,具体看情况。示例:

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
// public class TextSwitcherActivity extends AppCompatActivity implements ViewSwitcher.ViewFactory

...

private void setFactory() {
mSwitcher.setFactory(this);
mTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
TextView t = new TextView(TextSwitcherActivity.this);
t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
t.setTextSize(36);
return t;
}
});
}

// 实现接口中的方法
@Override
public View makeView() {
TextView t = new TextView(this);
t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
t.setTextSize(36);
return t;
}

...

4、为 TextSwitcher 设置 动画

1
2
3
4
5
6
7
8
9
Animation in = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
mSwitcher.setInAnimation(in);
mSwitcher.setOutAnimation(out);

mTextSwitcher.setInAnimation(this, android.R.anim.fade_in);
mTextSwitcher.setOutAnimation(this, android.R.anim.fade_out);

很简单,没有什么要说的。

5、更新 TextSwitcher 的内容

1
2
3
4
5
6
7
private void updateCounter() {
mSwitcher.setText(String.valueOf(mCounter));
}

private void onSwitchText() {
mTextSwitcher.setText(TEXTS[mTextsPosition]);
}

对,就和 TextView 一样,调用 TextSwitcher 的 setText() 方法即可,每次调用该方法的时候都会使用你所指定的动画来切换内容。

ImageSwitcher 简单使用

先看效果:

ImageSwitcher演示

1、在布局文件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageSwitcher
android:id="@+id/switcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Gallery
android:id="@+id/gallery"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#55000000"
android:gravity="center_vertical"
android:spacing="16dp" />
</RelativeLayout>

直接从 APIDemos 里面拷出来的代码,大家凑合着看吧。

2、设置 Factory
这和 TextSwitcher 没什么不同,不过要注意的是 ImageSwitcher 是用来为 Image 切换提供视觉效果的,也就是说,它里面要放 ImageView。

1
2
3
4
5
6
7
8
9
10
11
12
mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);
mSwitcher.setFactory(this);

@Override
public View makeView() {
ImageView i = new ImageView(this);
i.setBackgroundColor(0xFF000000);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
return i;
}

3、设置动画

1
2
3
4
mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));
mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));

4、切换图片

1
mSwitcher.setImageResource(mImageIds[position]);

对,ImageSwitcher 提供了和 ImageView 一样的方法,用来设置 Image。

小结

TextSwitcher 与 ImageSwitcher 的使用很简单,总结一下就是下面几步:

  1. 获取实例
    一般是先在布局文件中写好,然后通过 findViewById() 方法获取,当然也可以直接在代码中 new
  2. 为 ViewSwitcher 指定 Factory
    通过 viewSwitcher.setFactory() 方法设置,Factory 的实现是情况而定
  3. 设置切换动画
    setInAnimation():设置换入动画
    setOutAnimation():设置换出动画
  4. 切换内容
    TextSwitcher 调用 setText() 方法
    ImageSwitcher 调用 setImageXxx() 方法

好了关于 ViewSwitcher 的介绍到这里了,希望对你有用。

项目地址

AndroidHacks合集
动画篇

示例用到代码见:
TextSwitcherActivity.java
ImageSwitcherActivity.java
activity_textswitcher.xml
activity_image_switcher.xml

坚持原创技术分享,您的支持将鼓励我继续创作!