七、为动画制作小部件和布局

动画是现代应用用户界面设计的重要元素。然而,在设计中过度使用动画也很容易。在非游戏应用中使用动画的一般准则是——仅动画化用户交互和通知,并保持较短的持续时间,以便不会对用户体验产生负面影响。对于一款游戏来说,更多的动画一般是可以接受的(甚至是可以期待的)。

那么,为什么要激活用户交互,而不是(例如)应用的背景呢?首先,制作应用的背景动画会分散注意力,如果你试图捕捉或向用户呈现重要信息,这是不专业的(不管它看起来有多好)。动画在通知方面也非常重要。屏幕上的移动会吸引注意力,因此通常会是一个大的弹出对话框可以被一个小的动画图标代替。这种图标的一个完美例子是“下载”图标,当安卓市场应用下载新软件或更新时,该图标位于安卓设备通知区域的左上角。

布局动画和过渡为用户提供了有用的状态信息。当使用屏幕过渡时,你告诉你的用户刚刚发生了什么,或者将要发生什么。不同的转换对用户来说意味着不同的事件,知道每个不同的活动使用什么样的转换会让用户知道将要采取什么样的行动。布局动画是用户反馈的一个重要部分,忽略它们或在错误的地方使用错误的动画会让用户感到恼火,或有点困惑(“变得茫然”)。使用正确的动画将改善用户体验,甚至可以通过给他们关于他们下一步要做什么的简短提示来加快他们对应用的使用。

在本章中,我们将看到两种主要类型的动画——小部件动画和布局动画。我们将看看安卓提供的标准动画结构,以及如何创建新的动画类型和扩展现有的动画类型。我们还将关注动画的时机和“良好实践”的使用,并在不减慢用户速度或分散用户注意力的情况下让用户保持快乐。

使用标准安卓动画

安卓系统中的任何ViewViewGroup对象都可以附带一个动画。动画通常被定义为 XML 文件中的应用资源,安卓在 android包中提供了一些有用的默认值。安卓还包括几个专门为处理动画而设计的View类。有了这些类,你会发现它们有布局属性,允许你设置特定类型的动画,用于特定的动作。然而,动画通常不在布局文件中指定,而是依赖于 Java 代码来设置和启动 Animation对象。

动画通常不被指定为布局 XML 的一部分的主要原因很简单——它们应该在什么时候运行?许多动画可以作为对用户输入的响应,让用户知道发生了什么。大多数动画都会以某种方式被用户的动作触发(除非它们是作为通知出现的)。因此,您需要指定两者——在小部件上运行哪个动画,以及关于动画应该何时运行的信号。默认的安卓动画将立即开始制作动画,而其他动画结构在开始之前可能会有预定的延迟。

行动时间-制作新闻提要的动画

我们将从创建一个选择器Activity和一个简单的 NewsFeedActivity开始。在新闻提要中,我们将使用计时器将最新的标题“进出”动画化。在这个例子中,我们将使用安卓提供的一些默认动画,并主要通过布局资源来驱动这个过程。

  1. 创建一个包含本章动画示例的新项目,主Activity名为 AnimationSelectionActivity :

    java android create project -n AnimationExamples -p AnimationExamples -k com.packtpub.animations -a AnimationSelector -t 3

  2. 在编辑器或 IDE 中打开res/layout/main.xml布局文件。

  3. 清除布局资源的默认内容。
  4. 声明垂直LinearLayout消耗所有可用的屏幕空间:

    java <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">

  5. 创建一个标记为News FeedButton链接到第一个动画示例:

    java <Button android:id="@+id/news_feed" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:text="News Feed"/>

  6. 创建一个名为news.xml的新布局资源文件。

  7. 声明一个包含所有可用屏幕空间的垂直【T0:

    java <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">"

  8. LinearLayout添加一个TextSwitcher对象,指定默认“幻灯片”动画的“入”和“出”动画:

    java <TextSwitcher android:id="@+id/news_feed" android:inAnimation="@android:anim/slide_in_left" android:outAnimation="@android:anim/slide_out_right" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=""/>

  9. 在编辑器或 IDE 中打开res/values/strings.xml文件。

  10. 声明一个名为headlines的字符串数组,其中包含一些模拟新闻标题的元素:

    java <string-array name="headlines"> <item>Pwnies found to inhabit Mars</item> <item>Geeks invent \"atoms\"</item> <item>Politician found not lying!</item> <!-- add some more items here if you like --> </string-array>

  11. 在生成的根包中,声明一个名为NewsFeedActivity.java的新的 Java 源文件。

  12. 在你的AndroidManifest.xml文件中注册NewsFeedActivity类:

    java <activity android:name=".NewsFeedActivity" android:label="News Feed" />

  13. 新类应该扩展Activity类,实现Runnable :

    java public class NewsFeedActivity extends Activity implements Runnable {

  14. 声明Handler作为更改标题的计时结构:

    java private final Handler handler = new Handler();

  15. 我们需要引用TextSwitcher对象:

    java private TextSwitcher newsFeed;

  16. 声明一个字符串数组来保存您添加到strings.xml文件中的模拟标题:

    java private String[] headlines;

  17. 您还需要跟踪当前显示的标题:

    java private int headlineIndex;

  18. 覆盖 onCreate方法:

    java protected void onCreate(final Bundle savedInstanceState) {

  19. 调用ActivityonCreate方法:

    java super.onCreate(savedInstanceState);

  20. 将内容视图设置为news布局资源:

    java setContentView(R.layout.news);

  21. strings.xml应用资源文件

    java headlines = getResources().getStringArray(R.array.headlines);

    中存储对标题字符串数组的引用 22. 找到TextSwitcher小部件,并将其分配给前面声明的字段:

    java newsFeed = (TextSwitcher)findViewById(R.id.news_feed);

  22. TextSwitcherViewFactory设置为一个新的匿名类,当被询问时将创建TextView对象:

    java newsFeed.setFactory(new ViewFactory() { public View makeView() { return new TextView(NewsFeedActivity.this); } });

  23. 超越onStart方法:

    java protected void onStart() {

  24. 调用Activity类的onStart方法:

    java super.onStart();

  25. 重置headlineIndex以便我们从第一个标题开始:

    java headlineIndex = 0;

  26. 使用Handler :

    java handler.postDelayed(this, 3000);

    NewsFeedActivity作为延迟动作发布 28. 覆盖 onStop方法:

    java protected void onStop() {

  27. 调用Activity类的onStop方法:

    java super.onStop();

  28. 删除对NewsFeedActivity :

    java handler.removeCallbacks(this);

    的任何未决呼叫 31. 实现run方法,我们将使用该方法切换到下一个标题:

    java public void run() {

  29. 打开一个try块,交换里面的标题。

  30. 使用TextSwitcher.setText方法切换到下一个标题:

    java newsFeed.setText(headlines[headlineIndex++]);

  31. 如果headlineIndex超过标题总数,将headlineIndex重置为零:

    java if(headlineIndex >= headlines.length) { headlineIndex = 0; }

  32. 关闭try块,增加一个finally块。在finally区,将NewsFeedActivity放回Handler队列:

    java finally { handler.postDelayed(this, 3000); }

  33. 在编辑器或 IDE 中打开自动生成的AnimationSelector Java 源码。

  34. AnimationSelector类需要实现OnClickListener :

    java public class AnimationSelector extends Activity implements OnClickListener {

  35. onCreate方法中,确保内容视图设置为之前创建的main布局资源:

    java setContentView(R.layout.main);

  36. 找到声明的Button,将其OnClickListener设置为this :

    java ((Button)findViewById(R.id.news_feed)). setOnClickListener(this);

  37. 申报onClick方法:

    java public void onClick(final View view) {

  38. 使用开关确定点击了哪个View:

    java switch(view.getId()) {

  39. 如果是新闻提要Button,那就用下面的case :

    java case R.id.news_feed:

  40. 使用新的Intent :

    java startActivity(new Intent(this, NewsFeedActivity.class));

    启动NewsFeedActivity 44. 脱离switch语句,从而完成onClick方法。

刚刚发生了什么?

TextSwitcher是动画工具View的一个例子。在这种情况下,它是在新闻标题之间交换的完美结构,一次显示一个标题,并在每个文本之间动画转换。TextSwitcher对象创建两个TextView对象(使用匿名的ViewFactory类)。当您使用 setText方法时,TextSwitcher会更改“离屏”TextView的文本,并在“离屏”TextView和“离屏”TextView之间设置过渡动画(显示新的文本内容)。

TextSwitcher类要求您为其指定两个动画资源,以便创建其过渡效果:

  • 将文本动画显示在屏幕上
  • 动画显示屏幕外的文本

在前面的例子中,我们使用了默认的 slide_in_leftslide_out_right动画。这两个都是基于翻译的动画的例子,因为它们实际上改变了TextView对象的“在屏幕上”的位置,以创建它们的效果。

使用翻转器和切换器部件

本章的第一个例子使用了TextSwitcher类,这是标准安卓应用编程接口中的一个动画View类。还有其他几个动画实用程序类,其中一些你可能以前遇到过(比如ImageSwitcher)。TextSwitcherImageSwitcher都是有亲缘关系的类,都是继承了比较通用的ViewSwitcher类。

ViewSwitcher类是一个通用的动画工具,它定义了我们在前面的例子中匿名实现的ViewFactory接口。一个ViewSwitcher是一个ViewGroup只有两个孩子的View对象。一个显示在屏幕上,另一个隐藏起来。 getNext实用程序方法可以让你找出哪个是View的“离屏”对象。

虽然您通常使用 ViewFactory来填充ViewSwitcher,但是您可以选择手动填充。您可以使用从ViewGroup继承的 addView方法填充示例中的TextSwitcher

Using flipper and switcher widgets

使用图像切换器和文本切换器实现

ImageSwitcherTextSwitcher类是ViewSwitcher的专门实现,理解它们包含的View对象的类型。当您调用TextSwitcher对象的 setText方法时,这很像在包含两个TextView子对象的ViewSwitcher上调用以下代码片段:

((TextView)switcher.getNext()).setText("Next text to display");
switcher.showNext();

TextSwitcher可用于显示内容,如(如示例中的)新闻提要,或与安卓通知区域一样,显示不适合单行的文本内容。当动画向上运行文本时,在TextSwitcher中显示多行特别有效,使文本在TextSwitcher对象后面向上滚动。

一个ImageSwitcher最常用于画廊、幻灯片放映或类似的结构。您也可以使用ImageSwitcher允许用户从一个小的图像列表中进行选择,例如一个简短的登录头像列表。

有一个围棋英雄——填充文本切换器

作为在新闻提要示例中用ViewFactory填充TextSwitcher的替代方法,尝试在 XML 布局资源中填充它。请记住,它只需要两个TextView子部件。如果你没弄错的话,试着给两个TextView对象不同的字体颜色和样式。

制作布局小部件的动画

使用动画工具小部件,如 TextSwitcherImageSwitcher 可以让你随着时间的推移显示比你一次能在屏幕上显示的更多的信息。ViewGroup对象也可以通过LayoutAnimationController类在没有任何严重修改的情况下进行动画制作。但是,在这种情况下,需要在您的 Java 代码中添加动画。

一个LayoutAnimationController最好用于在ViewGroup出现时或者在它从屏幕上消失之前创建“进入”或“退出”效果。控制器只需在指定的ViewGroup的每个View子代上启动指定的动画。然而,它不一定要同时完成,也不一定要按顺序完成。您可以轻松配置LayoutAnimationController在每个子部件上的动画开始之间留出一点延迟,从而创建交错效果。

如果正确应用于LinearLayout,可以获得类似下图所示的结果:

Animating layout widgets

行动时间-动画化网格视图

GridView类有自己的LayoutAnimationController专门设计来根据行和列来激活它,允许比标准的 LayoutAnimationController更复杂的效果。对于“动画”示例的下一部分,我们将从GridView中构建一个可爱的颜色选择器。当选择器第一次出现在屏幕上时,每个色样都会淡入,从左上角开始,到右下角结束。

  1. 首先在名为ColorAdapter.java的项目根包中声明一个新的 Java 源文件,它将为GridView生成色板。
  2. T0 需要延长BaseAdapter来照顾锅炉板Adapter要求:

    java public class ColorAdapter extends BaseAdapter {

  3. ColorAdapter将创建指定数量的行和列,相同的数字将显示在GridView上:

    ```java private final int rows; private final int cols;

    public ColorAdapter(int rows, int cols) { this.rows = rows; this.cols = cols; } ```

  4. ColorAdapter提供的项目数是行数乘以列数:

    java public int getCount() return rows * cols; }

  5. 颜色的标识是找到它的位置或索引:

    java public long getItemId(int pos) { return pos; }

  6. 我们使用一个实用的方法从“列表”中的一个索引合成颜色。对于这个功能,我们使用了安卓Color类中的 HSVtoRGB方法:

    java private int getColor(int pos) { float h = (float)pos / (float)getCount(); return Color.HSVToColor(new float[]{h * 360f, 1f, 1f}); }

  7. 适配器模型中索引处的项目作为其颜色值返回:

    java public Object getItem(int pos) { return getColor(pos); }

  8. 为了创建颜色样本View对象,我们像往常一样实现AdaptergetView方法:

    java public View getView(int pos, View reuse, ViewGroup parent) {

  9. 我们返回的View将是一个ImageView对象,所以我们要么重用父小部件给定的对象,要么创建一个新的:

    java ImageView view = reuse instanceof ImageView ? (ImageView)reuse : new ImageView(parent.getContext());

  10. 我们使用ColorDrawable类将ImageView填充为我们的getColor实用程序方法指定的颜色:

    java view.setImageDrawable(new ColorDrawable(getColor(pos)));

  11. ImageView需要设置android.widget.AbsListView.LayoutParams,然后可以返回GridView显示:

    java view.setLayoutParams(new LayoutParams(16, 16)); return view;

  12. 创建一个名为res/layout/colors.xml的新的 XML 布局资源文件来保存GridView的声明,该声明将作为颜色选择器。

  13. colors.xml布局文件的内容只是一个单独的GridView小部件:

    java <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/colors" android:verticalSpacing="5dip" android:horizontalSpacing="5dip" android:stretchMode="columnWidth" android:gravity="center" android:layout_width="fill_parent" android:layout_height="fill_parent" />

  14. AnimationExamples项目的根包中定义另一个新的 Java 源文件。说出这个ColorSelectorActivity.java

  15. 新的类声明应该扩展Activity :

    java public class ColorSelectorActivity extends Activity {

  16. 像平常一样覆盖onCreate方法,并将内容视图设置为您刚刚编写的colors XML 布局资源:

    java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.colors);

  17. 现在,您可以从android.view.animation包中使用方便的AnimationUtils类加载默认的Android“淡入”动画:

    java Animation animation = AnimationUtils.loadAnimation( this, android.R.anim.fade_in);

  18. 为了正确设置GridView的动画,你需要实例化一个新的GridLayoutAnimationController对象,给它传递“淡入”动画:

    java GridLayoutAnimationController animationController = new GridLayoutAnimationController( animation, 0.2f, 0.2f);

  19. 现在寻找你在colors.xml文件中声明的【T0:

    java GridView view = (GridView)findViewById(R.id.colors);

  20. GridView中的列数设置为10(注意,我们没有像您通常所做的那样在 XML 布局资源中这样做):

    java view.setNumColumns(10);

  21. 当您将GridView的适配器设置为ColorAdapter时,您还需要知道列的数量,最简单的方法是将两者都保存在 Java 中:

    java view.setAdapter(new ColorAdapter(10, 10));

  22. 现在view对象已经为GridLayoutAnimationController准备好了:

    java view.setLayoutAnimation(animationController);

  23. 为了在屏幕显示时开始动画,我们覆盖onStart方法。正是在这里,我们再次查找GridView并开始动画:

    java protected void onStart() { super.onStart(); ((GridView)findViewById(R.id.colors)). getLayoutAnimation().start(); }

  24. 为了将这个新示例与其他动画示例集成在一起,您需要在编辑器或 IDE 中打开res/layout/main.xml文件。

  25. LinearLayout的末尾添加一个新的Button,我们将使用它来开始颜色选择示例:

    java <Button android:id="@+id/colors" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:text="Color Selector" />

  26. 在编辑器或 IDE 中打开AnimationSelector源文件。

  27. 设置news_feed ButtonOnClickListener后,以同样的方式找到并设置新colors ButtonOnClickListener:

    java ((Button)findViewById(R.id.colors)).setOnClickListener(this);

  28. onClick方法中,在news_feed Buttonswitch case之后,为新的colors Button添加另一个switch case,并启动ColorSelectorActivity :

    java case R.id.colors: startActivity(new Intent(this, ColorSelectorActivity.class)); break;

  29. 在编辑器或 IDE 中打开AndroidManifest.xml文件。

  30. <application>部分的底部,注册新的ColorSelectorActivity :

    java <activity android:name=".ColorSelectorActivity" android:label="Your Favorite Color" />

刚刚发生了什么?

新示例利用GridLayoutAnimationController在前一个动画开始后的几分之一秒开始每个“淡入”动画。这将创建从屏幕左上角到右下角出现的色板的流畅动画效果。

当你实例化一个GridLayoutAnimationController时,它要求你提供动画和两个参数,这两个参数指示下一行或下一列开始动画之间的时间。给定的延迟不是以“直接”时间格式指定的,而是由给定动画需要多长时间才能完成来指定的。在我们的例子中,如果动画花了一秒钟完成,每个动画开始之间的延迟将是 200 毫秒,因为延迟被指定为0.2

事实上,当这个Activity变得可见时,我们对样本进行动画制作,这有效地使其成为过渡动画,将用户引入这个新屏幕。对于这些类型的动画,在给出令人愉悦的介绍的同时,花尽可能少的时间是非常必要的。运行新示例时,您应该会看到一个类似于下图所示的动画:

What just happened?

创建自定义动画

到目前为止,我们已经探索了在普通小部件上使用安卓的股票动画,但是将自定义动画应用到不是为动画构建的小部件上呢?Android 包括对四种基本动画类型的支持,可应用于View对象:

  • 翻译/移动
  • 辐状的
  • 规模
  • 阿尔法/透明

这些不同的动画结构可以单独应用,也可以合并在一个动画集中,三者的任意组合可以同时运行。通过在动画开始前创建一个延迟时间,您可以通过让简单的动画集相互跟随来创建复杂的动画。

像安卓中的许多东西一样,创建自己的自定义动画最简单的方法是在资源 XML 文件中定义它。安卓使用的动画格式中的元素直接对应 android.animation.view包中的类。动画文件还可以引用其他动画资源中的动画,这使得合成复杂动画和重用简单动画变得更加容易。

行动时间-编写自定义动画

编写自定义动画非常简单,但并不完全直观。在这一节中,您将定义一个自定义动画,它会将其动画小部件的大小增加五倍,同时使其褪色,直到完全透明。

  1. 新建一个名为res/anim/vanish.xml的 XML 资源文件,在编辑器或 IDE 中打开。
  2. 动画文件的根元素将是动画set元素:

    java <set xmlns:android="http://schemas.android.com/apk/res/android">

  3. <set>元素中,声明一个元素来定义放大动画:

    java <scale />

  4. 放大动画的持续时间需要设置为300毫秒:

    java android:duration="300"

  5. 动画从原始大小开始缩放:

    java android:fromXScale="1.0" android:fromYScale="1.0"

  6. 缩放动画需要将尺寸增加5.0 :

    java android:toXScale="5.0" android:toYScale="5.0"

    倍 7. 我们希望比例从小部件的中心开始扩展:

    java android:pivotX="50%" android:pivotY="50%"

  7. 元素的最后一部分定义了动画的加速度曲线。这里,我们希望秤在运行时减速:

    java android:interpolator="@android:anim/decelerate_interpolator"

  8. 接下来,定义一个新元素来处理动画的淡出部分:

    java <alpha />

  9. 淡出动画的持续时间也是300毫秒:

    java android:duration="300"

  10. 我们从无透明度开始:

    java android:fromAlpha="1.0"

  11. 淡出以一个完全不可见的小部件结束:

    java android:toAlpha="0.0"

  12. 淡出应该在运行时加速,所以我们使用加速插值器:

    java android:interpolator="@android:anim/accelerate_interpolator"

刚刚发生了什么?

这是一个相对简单的动画集,但是它的效果在视觉上是令人愉悦的。将动画保持在300毫秒足够快,不会干扰用户的交互,但只要足够长,用户就能完全看到。

在动画 <set>元素中定义动画时,每个未设置的子动画都需要定义其duration<set>元素没有自己的duration概念。但是,您可以为整个集合定义一个单独的interpolator来共享。

<scale>动画默认情况下会以左上角为“枢轴”点缩放小部件,使小部件向右下方生长,而不是向左上方生长。这导致了一个不平衡的动画,不是很吸引人。在前面的示例中,缩放动画在枢轴位于动画小部件中心的情况下运行。

What just happened?

行动时间——让按钮消失

那么我们如何将漂亮闪亮的动画应用到Button对象上呢?Button对象没有动画属性,所以不能直接从布局资源文件中引用。我们想要的是点击Button小部件时运行的动画。

  1. 新建一个名为res/layout/vanish.xml的布局资源文件,在编辑器或 IDE 中打开。
  2. 在新布局的根部,声明一个RelativeLayout元素:

    java <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">

  3. Button需要好看又大,以屏幕为中心。为此,我们给它一些内部填充:

    java <Button android:id="@+id/vanish" android:paddingTop="20dip" android:paddingBottom="20dip" android:paddingLeft="60dip" android:paddingRight="60dip" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Vanish" />

  4. 在名为VanishingButtonActivity.javaAnimationExamples项目的根包中创建新的 Java 源文件。

  5. 新类需要扩展Activity并实现OnClickListener接口:

    java public class VanishingButtonActivity extends Activity implements OnClickListener {

  6. 覆盖onCreate方法并调用Activity.onCreate方法执行所需的安卓设置:

    java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

  7. 将内容视图设置为新的vanish布局资源:

    java setContentView(R.layout.vanish);

  8. 找到在 XML 布局资源中声明的Button小部件,并设置其OnClickListener :

    java Button button = (Button)findViewById(R.id.vanish); button.setOnClickListener(this);

  9. 执行OnClickListeneronClick方法:

    java public void onClick(View clicked) {

  10. 从资源文件

    java Animation vanish = AnimationUtils.loadAnimation( this, R.anim.vanish);

    加载Animation 11. 启动Button对象上的Animation:

    java findViewById(R.id.vanish).startAnimation(vanish);

  11. 在编辑器或 IDE 中打开AndroidManifest.xml文件。

  12. 用显示标签

    java <activity android:name=".VanishingButtonActivity" android:label="Vanishing Button" />

    <application>部分的末尾声明VanishingButtonActivity 14. 在编辑器或 IDE 中打开res/layout/main.xml布局资源。 15. 在LinearLayout的末尾增加一个新的Button,激活VanishingButtonActivity :

    java <Button android:id="@+id/vanish" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:text="Vanishing Button" />

  13. 在编辑器或 IDE 中打开AnimationSelector Java 源文件。

  14. onCreate方法结束时,从布局中获取新的vanish Button,并设置其OnClickListener :

    java ((Button)findViewById(R.id.vanish)).setOnClickListener(this);

  15. onClick方法中,增加一个新的开关箱来启动VanishingButtonActivity :

    java case R.id.vanish: startActivity(new Intent( this, VanishingButtonActivity.class)); break;

刚刚发生了什么?

前面例子的添加将在屏幕中间显示一个Button。点击时,Button会被 vanish动画突变300毫秒。当它完成后,动画将不再对Button有任何影响。这是动画的一个重要特征——当它们完成时,它们动画化的小部件会返回到其原始状态。

同样重要的是要注意,不是小部件本身被动画修改,而是它所绘制的Canvas的状态。这与在 Java AWT 中修改GraphicsGraphics2D对象的状态,或者在小部件使用Graphics对象绘制自己之前修改 Swing 的概念非常相似。

在下面的图片中,你可以看到动画在点击Button时的效果。Button实际上是为动画中的每一帧重新绘制的,并且在此期间保持完全活动。

What just happened?

总结

在本章中,我们探讨了将动画应用于用户界面各个部分的各种方法。我们探索了一些小部件是如何被设计成动画的。布局可以为进出Activity的过渡设置动画。

默认情况下,安卓资源中有几个简单的动画,但最终创建您自己的动画并手动将其应用到您的用户界面上,可以为您的用户创造最具视觉吸引力和用户友好的体验。

移动设备上的许多应用需要在屏幕上呈现大量信息,并以易于吸收的方式呈现。在下一章中,我们将探讨关于以友好和有用的方式向用户呈现信息的用户界面设计。这使用户能够以快速简便的方式尽可能快地访问他们需要的信息,同时不限制他们可以访问的信息。