七、为动画制作小部件和布局
动画是现代应用用户界面设计的重要元素。然而,在设计中过度使用动画也很容易。在非游戏应用中使用动画的一般准则是——仅动画化用户交互和通知,并保持较短的持续时间,以便不会对用户体验产生负面影响。对于一款游戏来说,更多的动画一般是可以接受的(甚至是可以期待的)。
那么,为什么要激活用户交互,而不是(例如)应用的背景呢?首先,制作应用的背景动画会分散注意力,如果你试图捕捉或向用户呈现重要信息,这是不专业的(不管它看起来有多好)。动画在通知方面也非常重要。屏幕上的移动会吸引注意力,因此通常会是一个大的弹出对话框可以被一个小的动画图标代替。这种图标的一个完美例子是“下载”图标,当安卓市场应用下载新软件或更新时,该图标位于安卓设备通知区域的左上角。
布局动画和过渡为用户提供了有用的状态信息。当使用屏幕过渡时,你告诉你的用户刚刚发生了什么,或者将要发生什么。不同的转换对用户来说意味着不同的事件,知道每个不同的活动使用什么样的转换会让用户知道将要采取什么样的行动。布局动画是用户反馈的一个重要部分,忽略它们或在错误的地方使用错误的动画会让用户感到恼火,或有点困惑(“变得茫然”)。使用正确的动画将改善用户体验,甚至可以通过给他们关于他们下一步要做什么的简短提示来加快他们对应用的使用。
在本章中,我们将看到两种主要类型的动画——小部件动画和布局动画。我们将看看安卓提供的标准动画结构,以及如何创建新的动画类型和扩展现有的动画类型。我们还将关注动画的时机和“良好实践”的使用,并在不减慢用户速度或分散用户注意力的情况下让用户保持快乐。
使用标准安卓动画
安卓系统中的任何View
或ViewGroup
对象都可以附带一个动画。动画通常被定义为 XML 文件中的应用资源,安卓在 android
包中提供了一些有用的默认值。安卓还包括几个专门为处理动画而设计的View
类。有了这些类,你会发现它们有布局属性,允许你设置特定类型的动画,用于特定的动作。然而,动画通常不在布局文件中指定,而是依赖于 Java 代码来设置和启动 Animation
对象。
动画通常不被指定为布局 XML 的一部分的主要原因很简单——它们应该在什么时候运行?许多动画可以作为对用户输入的响应,让用户知道发生了什么。大多数动画都会以某种方式被用户的动作触发(除非它们是作为通知出现的)。因此,您需要指定两者——在小部件上运行哪个动画,以及关于动画应该何时运行的信号。默认的安卓动画将立即开始制作动画,而其他动画结构在开始之前可能会有预定的延迟。
行动时间-制作新闻提要的动画
我们将从创建一个选择器Activity
和一个简单的 NewsFeedActivity
开始。在新闻提要中,我们将使用计时器将最新的标题“进出”动画化。在这个例子中,我们将使用安卓提供的一些默认动画,并主要通过布局资源来驱动这个过程。
-
创建一个包含本章动画示例的新项目,主
Activity
名为AnimationSelectionActivity
:java android create project -n AnimationExamples -p AnimationExamples -k com.packtpub.animations -a AnimationSelector -t 3
-
在编辑器或 IDE 中打开
res/layout/main.xml
布局文件。 - 清除布局资源的默认内容。
-
声明垂直
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">
-
创建一个标记为
News Feed
的Button
链接到第一个动画示例: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"/>
-
创建一个名为
news.xml
的新布局资源文件。 -
声明一个包含所有可用屏幕空间的垂直【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">"
-
向
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=""/>
-
在编辑器或 IDE 中打开
res/values/strings.xml
文件。 -
声明一个名为
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>
-
在生成的根包中,声明一个名为
NewsFeedActivity.java
的新的 Java 源文件。 -
在你的
AndroidManifest.xml
文件中注册NewsFeedActivity
类:java <activity android:name=".NewsFeedActivity" android:label="News Feed" />
-
新类应该扩展
Activity
类,实现Runnable
:java public class NewsFeedActivity extends Activity implements Runnable {
-
声明
Handler
作为更改标题的计时结构:java private final Handler handler = new Handler();
-
我们需要引用
TextSwitcher
对象:java private TextSwitcher newsFeed;
-
声明一个字符串数组来保存您添加到
strings.xml
文件中的模拟标题:java private String[] headlines;
-
您还需要跟踪当前显示的标题:
java private int headlineIndex;
-
覆盖
onCreate
方法:java protected void onCreate(final Bundle savedInstanceState) {
-
调用
Activity
的onCreate
方法:java super.onCreate(savedInstanceState);
-
将内容视图设置为
news
布局资源:java setContentView(R.layout.news);
-
从
strings.xml
应用资源文件java headlines = getResources().getStringArray(R.array.headlines);
中存储对标题字符串数组的引用 22. 找到
TextSwitcher
小部件,并将其分配给前面声明的字段:java newsFeed = (TextSwitcher)findViewById(R.id.news_feed);
-
将
TextSwitcher
的ViewFactory
设置为一个新的匿名类,当被询问时将创建TextView
对象:java newsFeed.setFactory(new ViewFactory() { public View makeView() { return new TextView(NewsFeedActivity.this); } });
-
超越
onStart
方法:java protected void onStart() {
-
调用
Activity
类的onStart
方法:java super.onStart();
-
重置
headlineIndex
以便我们从第一个标题开始:java headlineIndex = 0;
-
使用
Handler
:java handler.postDelayed(this, 3000);
将
NewsFeedActivity
作为延迟动作发布 28. 覆盖onStop
方法:java protected void onStop() {
-
调用
Activity
类的onStop
方法:java super.onStop();
-
删除对
NewsFeedActivity
:java handler.removeCallbacks(this);
的任何未决呼叫 31. 实现
run
方法,我们将使用该方法切换到下一个标题:java public void run() {
-
打开一个
try
块,交换里面的标题。 -
使用
TextSwitcher.setText
方法切换到下一个标题:java newsFeed.setText(headlines[headlineIndex++]);
-
如果
headlineIndex
超过标题总数,将headlineIndex
重置为零:java if(headlineIndex >= headlines.length) { headlineIndex = 0; }
-
关闭
try
块,增加一个finally
块。在finally
区,将NewsFeedActivity
放回Handler
队列:java finally { handler.postDelayed(this, 3000); }
-
在编辑器或 IDE 中打开自动生成的
AnimationSelector
Java 源码。 -
AnimationSelector
类需要实现OnClickListener
:java public class AnimationSelector extends Activity implements OnClickListener {
-
在
onCreate
方法中,确保内容视图设置为之前创建的main
布局资源:java setContentView(R.layout.main);
-
找到声明的
Button
,将其OnClickListener
设置为this
:java ((Button)findViewById(R.id.news_feed)). setOnClickListener(this);
-
申报
onClick
方法:java public void onClick(final View view) {
-
使用开关确定点击了哪个
View
:java switch(view.getId()) {
-
如果是新闻提要
Button
,那就用下面的case
:java case R.id.news_feed:
-
使用新的
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_left
和slide_out_right
动画。这两个都是基于翻译的动画的例子,因为它们实际上改变了TextView
对象的“在屏幕上”的位置,以创建它们的效果。
使用翻转器和切换器部件
本章的第一个例子使用了TextSwitcher
类,这是标准安卓应用编程接口中的一个动画View
类。还有其他几个动画实用程序类,其中一些你可能以前遇到过(比如ImageSwitcher
)。TextSwitcher
和 ImageSwitcher
都是有亲缘关系的类,都是继承了比较通用的ViewSwitcher
类。
ViewSwitcher
类是一个通用的动画工具,它定义了我们在前面的例子中匿名实现的ViewFactory
接口。一个ViewSwitcher
是一个ViewGroup
只有两个孩子的View
对象。一个显示在屏幕上,另一个隐藏起来。 getNext
实用程序方法可以让你找出哪个是View
的“离屏”对象。
虽然您通常使用 ViewFactory
来填充ViewSwitcher
,但是您可以选择手动填充。您可以使用从ViewGroup
继承的 addView
方法填充示例中的TextSwitcher
。
使用图像切换器和文本切换器实现
ImageSwitcher
和TextSwitcher
类是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
对象不同的字体颜色和样式。
制作布局小部件的动画
使用动画工具小部件,如 TextSwitcher
和ImageSwitcher
可以让你随着时间的推移显示比你一次能在屏幕上显示的更多的信息。ViewGroup
对象也可以通过LayoutAnimationController
类在没有任何严重修改的情况下进行动画制作。但是,在这种情况下,需要在您的 Java 代码中添加动画。
一个LayoutAnimationController
最好用于在ViewGroup
出现时或者在它从屏幕上消失之前创建“进入”或“退出”效果。控制器只需在指定的ViewGroup
的每个View
子代上启动指定的动画。然而,它不一定要同时完成,也不一定要按顺序完成。您可以轻松配置LayoutAnimationController
在每个子部件上的动画开始之间留出一点延迟,从而创建交错效果。
如果正确应用于LinearLayout
,可以获得类似下图所示的结果:
行动时间-动画化网格视图
GridView
类有自己的LayoutAnimationController
专门设计来根据行和列来激活它,允许比标准的 LayoutAnimationController
更复杂的效果。对于“动画”示例的下一部分,我们将从GridView
中构建一个可爱的颜色选择器。当选择器第一次出现在屏幕上时,每个色样都会淡入,从左上角开始,到右下角结束。
- 首先在名为
ColorAdapter.java
的项目根包中声明一个新的 Java 源文件,它将为GridView
生成色板。 -
T0 需要延长
BaseAdapter
来照顾锅炉板Adapter
要求:java public class ColorAdapter extends BaseAdapter {
-
ColorAdapter
将创建指定数量的行和列,相同的数字将显示在GridView
上:```java private final int rows; private final int cols;
public ColorAdapter(int rows, int cols) { this.rows = rows; this.cols = cols; } ```
-
ColorAdapter
提供的项目数是行数乘以列数:java public int getCount() return rows * cols; }
-
颜色的标识是找到它的位置或索引:
java public long getItemId(int pos) { return pos; }
-
我们使用一个实用的方法从“列表”中的一个索引合成颜色。对于这个功能,我们使用了安卓
Color
类中的HSVtoRGB
方法:java private int getColor(int pos) { float h = (float)pos / (float)getCount(); return Color.HSVToColor(new float[]{h * 360f, 1f, 1f}); }
-
适配器模型中索引处的项目作为其颜色值返回:
java public Object getItem(int pos) { return getColor(pos); }
-
为了创建颜色样本
View
对象,我们像往常一样实现Adapter
的getView
方法:java public View getView(int pos, View reuse, ViewGroup parent) {
-
我们返回的
View
将是一个ImageView
对象,所以我们要么重用父小部件给定的对象,要么创建一个新的:java ImageView view = reuse instanceof ImageView ? (ImageView)reuse : new ImageView(parent.getContext());
-
我们使用
ColorDrawable
类将ImageView
填充为我们的getColor
实用程序方法指定的颜色:java view.setImageDrawable(new ColorDrawable(getColor(pos)));
-
ImageView
需要设置android.widget.AbsListView.LayoutParams
,然后可以返回GridView
显示:java view.setLayoutParams(new LayoutParams(16, 16)); return view;
-
创建一个名为
res/layout/colors.xml
的新的 XML 布局资源文件来保存GridView
的声明,该声明将作为颜色选择器。 -
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" />
-
在
AnimationExamples
项目的根包中定义另一个新的 Java 源文件。说出这个ColorSelectorActivity.java
。 -
新的类声明应该扩展
Activity
:java public class ColorSelectorActivity extends Activity {
-
像平常一样覆盖
onCreate
方法,并将内容视图设置为您刚刚编写的colors
XML 布局资源:java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.colors);
-
现在,您可以从
android.view.animation
包中使用方便的AnimationUtils
类加载默认的Android
“淡入”动画:java Animation animation = AnimationUtils.loadAnimation( this, android.R.anim.fade_in);
-
为了正确设置
GridView
的动画,你需要实例化一个新的GridLayoutAnimationController
对象,给它传递“淡入”动画:java GridLayoutAnimationController animationController = new GridLayoutAnimationController( animation, 0.2f, 0.2f);
-
现在寻找你在
colors.xml
文件中声明的【T0:java GridView view = (GridView)findViewById(R.id.colors);
-
将
GridView
中的列数设置为10
(注意,我们没有像您通常所做的那样在 XML 布局资源中这样做):java view.setNumColumns(10);
-
当您将
GridView
的适配器设置为ColorAdapter
时,您还需要知道列的数量,最简单的方法是将两者都保存在 Java 中:java view.setAdapter(new ColorAdapter(10, 10));
-
现在
view
对象已经为GridLayoutAnimationController
准备好了:java view.setLayoutAnimation(animationController);
-
为了在屏幕显示时开始动画,我们覆盖
onStart
方法。正是在这里,我们再次查找GridView
并开始动画:java protected void onStart() { super.onStart(); ((GridView)findViewById(R.id.colors)). getLayoutAnimation().start(); }
-
为了将这个新示例与其他动画示例集成在一起,您需要在编辑器或 IDE 中打开
res/layout/main.xml
文件。 -
在
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" />
-
在编辑器或 IDE 中打开
AnimationSelector
源文件。 -
设置
news_feed Button
的OnClickListener
后,以同样的方式找到并设置新colors Button
的OnClickListener
:java ((Button)findViewById(R.id.colors)).setOnClickListener(this);
-
在
onClick
方法中,在news_feed Button
的switch case
之后,为新的colors Button
添加另一个switch case
,并启动ColorSelectorActivity
:java case R.id.colors: startActivity(new Intent(this, ColorSelectorActivity.class)); break;
-
在编辑器或 IDE 中打开
AndroidManifest.xml
文件。 -
在
<application>
部分的底部,注册新的ColorSelectorActivity
:java <activity android:name=".ColorSelectorActivity" android:label="Your Favorite Color" />
刚刚发生了什么?
新示例利用GridLayoutAnimationController
在前一个动画开始后的几分之一秒开始每个“淡入”动画。这将创建从屏幕左上角到右下角出现的色板的流畅动画效果。
当你实例化一个GridLayoutAnimationController
时,它要求你提供动画和两个参数,这两个参数指示下一行或下一列开始动画之间的时间。给定的延迟不是以“直接”时间格式指定的,而是由给定动画需要多长时间才能完成来指定的。在我们的例子中,如果动画花了一秒钟完成,每个动画开始之间的延迟将是 200 毫秒,因为延迟被指定为0.2
。
事实上,当这个Activity
变得可见时,我们对样本进行动画制作,这有效地使其成为过渡动画,将用户引入这个新屏幕。对于这些类型的动画,在给出令人愉悦的介绍的同时,花尽可能少的时间是非常必要的。运行新示例时,您应该会看到一个类似于下图所示的动画:
创建自定义动画
到目前为止,我们已经探索了在普通小部件上使用安卓的股票动画,但是将自定义动画应用到不是为动画构建的小部件上呢?Android 包括对四种基本动画类型的支持,可应用于View
对象:
- 翻译/移动
- 辐状的
- 规模
- 阿尔法/透明
这些不同的动画结构可以单独应用,也可以合并在一个动画集中,三者的任意组合可以同时运行。通过在动画开始前创建一个延迟时间,您可以通过让简单的动画集相互跟随来创建复杂的动画。
像安卓中的许多东西一样,创建自己的自定义动画最简单的方法是在资源 XML 文件中定义它。安卓使用的动画格式中的元素直接对应 android.animation.view
包中的类。动画文件还可以引用其他动画资源中的动画,这使得合成复杂动画和重用简单动画变得更加容易。
行动时间-编写自定义动画
编写自定义动画非常简单,但并不完全直观。在这一节中,您将定义一个自定义动画,它会将其动画小部件的大小增加五倍,同时使其褪色,直到完全透明。
- 新建一个名为
res/anim/vanish.xml
的 XML 资源文件,在编辑器或 IDE 中打开。 -
动画文件的根元素将是动画
set
元素:java <set xmlns:android="http://schemas.android.com/apk/res/android">
-
在
<set>
元素中,声明一个元素来定义放大动画:java <scale />
-
放大动画的持续时间需要设置为
300
毫秒:java android:duration="300"
-
动画从原始大小开始缩放:
java android:fromXScale="1.0" android:fromYScale="1.0"
-
缩放动画需要将尺寸增加
5.0
:java android:toXScale="5.0" android:toYScale="5.0"
倍 7. 我们希望比例从小部件的中心开始扩展:
java android:pivotX="50%" android:pivotY="50%"
-
元素的最后一部分定义了动画的加速度曲线。这里,我们希望秤在运行时减速:
java android:interpolator="@android:anim/decelerate_interpolator"
-
接下来,定义一个新元素来处理动画的淡出部分:
java <alpha />
-
淡出动画的持续时间也是
300
毫秒:java android:duration="300"
-
我们从无透明度开始:
java android:fromAlpha="1.0"
-
淡出以一个完全不可见的小部件结束:
java android:toAlpha="0.0"
-
淡出应该在运行时加速,所以我们使用加速插值器:
java android:interpolator="@android:anim/accelerate_interpolator"
刚刚发生了什么?
这是一个相对简单的动画集,但是它的效果在视觉上是令人愉悦的。将动画保持在300
毫秒足够快,不会干扰用户的交互,但只要足够长,用户就能完全看到。
在动画 <set>
元素中定义动画时,每个未设置的子动画都需要定义其duration
。<set>
元素没有自己的duration
概念。但是,您可以为整个集合定义一个单独的interpolator
来共享。
<scale>
动画默认情况下会以左上角为“枢轴”点缩放小部件,使小部件向右下方生长,而不是向左上方生长。这导致了一个不平衡的动画,不是很吸引人。在前面的示例中,缩放动画在枢轴位于动画小部件中心的情况下运行。
行动时间——让按钮消失
那么我们如何将漂亮闪亮的动画应用到Button
对象上呢?Button
对象没有动画属性,所以不能直接从布局资源文件中引用。我们想要的是点击Button
小部件时运行的动画。
- 新建一个名为
res/layout/vanish.xml
的布局资源文件,在编辑器或 IDE 中打开。 -
在新布局的根部,声明一个
RelativeLayout
元素:java <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">
-
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" />
-
在名为
VanishingButtonActivity.java
的AnimationExamples
项目的根包中创建新的 Java 源文件。 -
新类需要扩展
Activity
并实现OnClickListener
接口:java public class VanishingButtonActivity extends Activity implements OnClickListener {
-
覆盖
onCreate
方法并调用Activity.onCreate
方法执行所需的安卓设置:java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
-
将内容视图设置为新的
vanish
布局资源:java setContentView(R.layout.vanish);
-
找到在 XML 布局资源中声明的
Button
小部件,并设置其OnClickListener
:java Button button = (Button)findViewById(R.id.vanish); button.setOnClickListener(this);
-
执行
OnClickListener
的onClick
方法:java public void onClick(View clicked) {
-
从资源文件
java Animation vanish = AnimationUtils.loadAnimation( this, R.anim.vanish);
加载
Animation
11. 启动Button
对象上的Animation
:java findViewById(R.id.vanish).startAnimation(vanish);
-
在编辑器或 IDE 中打开
AndroidManifest.xml
文件。 -
用显示标签
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" />
-
在编辑器或 IDE 中打开
AnimationSelector
Java 源文件。 -
在
onCreate
方法结束时,从布局中获取新的vanish Button
,并设置其OnClickListener
:java ((Button)findViewById(R.id.vanish)).setOnClickListener(this);
-
在
onClick
方法中,增加一个新的开关箱来启动VanishingButtonActivity
:java case R.id.vanish: startActivity(new Intent( this, VanishingButtonActivity.class)); break;
刚刚发生了什么?
前面例子的添加将在屏幕中间显示一个Button
。点击时,Button
会被 vanish
动画突变300
毫秒。当它完成后,动画将不再对Button
有任何影响。这是动画的一个重要特征——当它们完成时,它们动画化的小部件会返回到其原始状态。
同样重要的是要注意,不是小部件本身被动画修改,而是它所绘制的Canvas
的状态。这与在 Java AWT 中修改Graphics
或Graphics2D
对象的状态,或者在小部件使用Graphics
对象绘制自己之前修改 Swing 的概念非常相似。
在下面的图片中,你可以看到动画在点击Button
时的效果。Button
实际上是为动画中的每一帧重新绘制的,并且在此期间保持完全活动。
总结
在本章中,我们探讨了将动画应用于用户界面各个部分的各种方法。我们探索了一些小部件是如何被设计成动画的。布局可以为进出Activity
的过渡设置动画。
默认情况下,安卓资源中有几个简单的动画,但最终创建您自己的动画并手动将其应用到您的用户界面上,可以为您的用户创造最具视觉吸引力和用户友好的体验。
移动设备上的许多应用需要在屏幕上呈现大量信息,并以易于吸收的方式呈现。在下一章中,我们将探讨关于以友好和有用的方式向用户呈现信息的用户界面设计。这使用户能够以快速简便的方式尽可能快地访问他们需要的信息,同时不限制他们可以访问的信息。
版权属于:月萌API www.moonapi.com,转载请注明出处