标签:
ViewAnimator是一个基类,它继承了FrameLayout。因此它表现出FrameLayout的特征,可以将多个View组“叠”在一起。
ViewAnimator可以在View切换时表现出动画效果。
ViewAnimator及其子类也是一组非常重要的UI组件,这种组件的主要功能是增加动画效果。从而使界面更加“炫”。
【ViewAnimator及其子类的继承关系】
图2.56
【ViewAnimator支持的常见XML属性】
android:animateFirstView 设置ViewAnimator显示第一个View组件时是否使用动画
android:inAnimation 设置ViewAnimator显示组件时使用的动画
android:outAnimation 设置ViewAnimator隐藏组件时使用的动画
★★★ ViewSwitcher的功能与用法 ★★★
ViewSwitcher代表了视图切换组件。它本身继承了FrameLayout。因此可以将多个View层叠加在一起,
每次只显示一个组件。当程序控制从一个View切换到另一个View时,ViewSwitcher支持指定动画效果。
为了给ViewSwitcher添加多个组件,一般通过调用ViewSwitcher的setFactory(ViewSwitcher.ViewFactory)方法为之设置ViewFactory,
并由该ViewFactory为之创建View即可。
实例:仿Android系统Launcher界面
本实例就是通过ViewSwitcher来实现Android4.2的Launcher分屏、左右滑动。
为了实现该效果,程序主界面考虑使用ViewSwitcher来组合多个GridView。每个GridView代表一个屏幕
的应用程序。
布局文件:
1 <RelativeLayout
2 xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent">
5 <!-- 定义一个ViewSwitcher组件 -->
6 <ViewSwitcher
7 android:id="@+id/viewSwitcher"
8 android:layout_width="fill_parent"
9 android:layout_height="fill_parent" />
10 <!-- 定义滚动到上一屏的按钮 -->
11 <Button
12 android:id="@+id/button_prev"
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content"
15 android:layout_alignParentBottom="true"
16 android:layout_alignParentLeft="true"
17 android:onClick="prev"
18 android:text="<" />
19 <!-- 定义滚动到下一屏的按钮 -->
20 <Button
21 android:id="@+id/button_next"
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:layout_alignParentBottom="true"
25 android:layout_alignParentRight="true"
26 android:onClick="next"
27 android:text=">" />
28 </RelativeLayout>
Activity代码:
1 public class ViewSwitcherTest extends Activity {
2 // 定义一个常量,用于显示每屏显示的应用程序数
3 public static final int NUMBER_PER_SCREEN = 12;
4
5 // 代表应用程序的内部类,
6 public static class DataItem {
7 // 应用程序名称
8 public String dataName;
9 // 应用程序图标
10 public Drawable drawable;
11 }
12
13 // 保存系统所有应用程序的List集合
14 private ArrayList<DataItem> items = new ArrayList<DataItem>();
15 // 记录当前正在显示第几屏的程序
16 private int screenNo = -1;
17 // 保存程序所占的总屏数
18 private int screenCount;
19 ViewSwitcher switcher;
20 // 创建LayoutInflater对象
21 LayoutInflater inflater;
22
23 @Override
24 public void onCreate(Bundle savedInstanceState) {
25 super.onCreate(savedInstanceState);
26 setContentView(R.layout.main);
27 inflater = LayoutInflater.from(ViewSwitcherTest.this);
28 // 创建一个包含40个元素的List集合,用于模拟包含40个应用程序
29 for (int i = 0; i < 40; i++) {
30 String label = "" + i;
31 Drawable drawable = getResources().getDrawable(
32 R.drawable.ic_launcher);
33 DataItem item = new DataItem();
34 item.dataName = label;
35 item.drawable = drawable;
36 items.add(item);
37 }
38 // 计算应用程序所占的总屏数。
39 // 如果应用程序的数量能整除NUMBER_PER_SCREEN,除法的结果就是总屏数。
40 // 如果不能整除,总屏数应该是除法的结果再加1。
41 screenCount = items.size() % NUMBER_PER_SCREEN == 0 ? items.size()
42 / NUMBER_PER_SCREEN : items.size() / NUMBER_PER_SCREEN + 1;
43 switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
44 switcher.setFactory(new ViewFactory() {
45 // 实际上就是返回一个GridView组件
46 @Override
47 public View makeView() {
48 // 加载R.layout.slidelistview组件,实际上就是一个GridView组件。
49 return inflater.inflate(R.layout.slidelistview, null);
50 }
51 });
52 // 页面加载时先显示第一屏。
53 next(null);
54 }
55
56 public void next(View v) {
57 if (screenNo < screenCount - 1) {
58 screenNo++;
59 // 为ViewSwitcher的组件显示过程设置动画
60 switcher.setInAnimation(this, R.anim.slide_in_right);
61 // 为ViewSwitcher的组件隐藏过程设置动画
62 switcher.setOutAnimation(this, R.anim.slide_out_left);
63 // 控制下一屏将要显示的GridView对应的 Adapter
64 ((GridView) switcher.getNextView()).setAdapter(adapter);
65 // 点击右边按钮,显示下一屏,
66 // 学习手势检测后,也可通过手势检测实现显示下一屏.
67 switcher.showNext(); // ①
68 }
69 }
70
71 public void prev(View v) {
72 if (screenNo > 0) {
73 screenNo--;
74 // 为ViewSwitcher的组件显示过程设置动画
75 switcher.setInAnimation(this, android.R.anim.slide_in_left);
76 // 为ViewSwitcher的组件隐藏过程设置动画
77 switcher.setOutAnimation(this, android.R.anim.slide_out_right);
78 // 控制下一屏将要显示的GridView对应的 Adapter
79 ((GridView) switcher.getNextView()).setAdapter(adapter);
80 // 点击左边按钮,显示上一屏,当然可以采用手势
81 // 学习手势检测后,也可通过手势检测实现显示上一屏.
82 switcher.showPrevious(); // ②
83 }
84 }
85
86 // 该BaseAdapter负责为每屏显示的GridView提供列表项
87 private BaseAdapter adapter = new BaseAdapter() {
88 @Override
89 public int getCount() {
90 // 如果已经到了最后一屏,且应用程序的数量不能整除NUMBER_PER_SCREEN
91 if (screenNo == screenCount - 1
92 && items.size() % NUMBER_PER_SCREEN != 0) {
93 // 最后一屏显示的程序数为应用程序的数量对NUMBER_PER_SCREEN求余
94 return items.size() % NUMBER_PER_SCREEN;
95 }
96 // 否则每屏显示的程序数量为NUMBER_PER_SCREEN
97 return NUMBER_PER_SCREEN;
98 }
99
100 @Override
101 public DataItem getItem(int position) {
102 // 根据screenNo计算第position个列表项的数据
103 return items.get(screenNo * NUMBER_PER_SCREEN + position);
104 }
105
106 @Override
107 public long getItemId(int position) {
108 return position;
109 }
110
111 @Override
112 public View getView(int position, View convertView, ViewGroup parent) {
113 View view = convertView;
114 if (convertView == null) {
115 // 加载R.layout.labelicon布局文件
116 view = inflater.inflate(R.layout.labelicon, null);
117 }
118 // 获取R.layout.labelicon布局文件中的ImageView组件,并为之设置图标
119 ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
120 imageView.setImageDrawable(getItem(position).drawable);
121 // 获取R.layout.labelicon布局文件中的TextView组件,并为之设置文本
122 TextView textView = (TextView) view.findViewById(R.id.textview);
123 textView.setText(getItem(position).dataName);
124 return view;
125 }
126 };
127 }
适配器Item的布局文件labelicon.xml。
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- 定义一个垂直的LinearLayout,该容器中放置一个ImageView和一个TextView -->
3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:gravity="center"
7 android:orientation="vertical" >
8 <ImageView
9 android:id="@+id/imageview"
10 android:layout_width="wrap_content"
11 android:layout_height="wrap_content" />
12 <TextView
13 android:id="@+id/textview"
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:gravity="center" />
17 </LinearLayout>
GridView布局slidelistview.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <GridView
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:numColumns="4" />
为了实现ViewSwitcher切换View时的动画效果,程序的事件处理方法中调用了ViewSwitcher的
setInAnimation()、setOutAnimation()来设置动画效果。
R.anim.slide_in_right
1 <?xml version="1.0" encoding="utf-8"?>
2 <set xmlns:android="http://schemas.android.com/apk/res/android">
3 <!-- 设置从右边拖进来的动画
4 android:duration指定动画持续时间 -->
5 <translate
6 android:fromXDelta="100%p"
7 android:toXDelta="0"
8 android:duration="@android:integer/config_mediumAnimTime" />
9 </set>
R.anim.slide_out_left
1 <?xml version="1.0" encoding="utf-8"?>
2 <set xmlns:android="http://schemas.android.com/apk/res/android">
3 <!-- 设置从左边拖出去的动画
4 android:duration指定动画持续时间 -->
5 <translate
6 android:fromXDelta="0"
7 android:toXDelta="-100%p"
8 android:duration="@android:integer/config_mediumAnimTime" />
9 </set>
★★★ 图片切换器(ImageSwitcher)的功能与用法 ★★★
ImageSwitcher继承了ViewSwitcher,并且重写了ViewSwitvher的showNext()、showPrevious().
因此它具有与ViewSwitvher相同的特征;可以在切换View组件时使用动画效果。
(1)为ImageSwitcher提供一个ViewFactory,该ViewFactory生成的View组件必须是ImageView。
(2)需要切换图片时,只要调用ImageSwitcher的setImageDrawable(Drawable drawable)。
setImageResource(int resid)和setImageURI(Uri uri)更换图片即可。
【提示】ImageSwitcher与ImageView的功能有点相似。它们都可用于显示图片,区别在于ImageSwitcher
的效果更炫,它可以指定图片切换时的动画效果。
实例:支持动画的图片浏览器
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:gravity="center_horizontal"
6 android:orientation="vertical" >
7
8 <!-- 定义一个GridView组件 -->
9 <GridView
10 android:id="@+id/grid01"
11 android:layout_width="fill_parent"
12 android:layout_height="wrap_content"
13 android:gravity="center"
14 android:horizontalSpacing="pt"
15 android:numColumns="4"
16 android:verticalSpacing="2pt" />
17
18 <!-- 定义一个ImageSwitcher组件 -->
19 <ImageSwitcher
20 android:id="@+id/switcher"
21 android:layout_width="300dp"
22 android:layout_height="300dp"
23 android:layout_gravity="center_horizontal"
24 android:inAnimation="@android:anim/fade_in"
25 android:outAnimation="@android:anim/fade_out" />
26 </LinearLayout>
1 public class ImageSwitcherTest extends Activity {
2 int[] imageIds = new int[] { R.drawable.bomb5, R.drawable.bomb6,
3 R.drawable.bomb7, R.drawable.bomb8, R.drawable.bomb9,
4 R.drawable.bomb10, R.drawable.bomb11, R.drawable.bomb12,
5 R.drawable.bomb13, R.drawable.bomb14, R.drawable.bomb15,
6 R.drawable.bomb16 };
7 ImageSwitcher switcher;
8
9 @Override
10 public void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
12 setContentView(R.layout.main);
13 // 创建一个List对象,List对象的元素是Map
14 List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
15 for (int i = 0; i < imageIds.length; i++) {
16 Map<String, Object> listItem = new HashMap<String, Object>();
17 listItem.put("image", imageIds[i]);
18 listItems.add(listItem);
19 }
20 // 获取显示图片的ImageSwitcher
21 switcher = (ImageSwitcher) findViewById(R.id.switcher);
22 // 为ImageSwitcher设置图片切换的动画效果
23 switcher.setFactory(new ViewFactory() {
24 @Override
25 public View makeView() {
26 // 创建ImageView对象
27 ImageView imageView = new ImageView(ImageSwitcherTest.this);
28 imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
29 imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
30 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
31 // 返回ImageView对象
32 return imageView;
33 }
34 });
35 // 创建一个SimpleAdapter
36 SimpleAdapter simpleAdapter = new SimpleAdapter(this,
37 listItems
38 // 使用/layout/cell.xml文件作为界面布局
39 , R.layout.cell, new String[] { "image" },
40 new int[] { R.id.image1 });
41 GridView grid = (GridView) findViewById(R.id.grid01);
42 // 为GridView设置Adapter
43 grid.setAdapter(simpleAdapter);
44 // 添加列表项被选中的监听器
45 grid.setOnItemSelectedListener(new OnItemSelectedListener() {
46 @Override
47 public void onItemSelected(AdapterView<?> parent, View view,
48 int position, long id) {
49 // 显示当前被选中的图片
50 switcher.setImageResource(imageIds[position]);
51 }
52 @Override
53 public void onNothingSelected(AdapterView<?> parent) {
54 }
55 });
56 // 添加列表项被单击的监听器
57 grid.setOnItemClickListener(new OnItemClickListener() {
58 @Override
59 public void onItemClick(AdapterView<?> parent, View view,
60 int position, long id) {
61 // 显示被单击的图片的图片
62 switcher.setImageResource(imageIds[position]);
63 }
64 });
65 }
66 }
★★★ 文本切换器(TextSwitcher)的功能与用法 ★★★
TextSwitcher继承了ViewSwitcher。可以在切换View组件时使用动画效果。与ImageSwitcher相似的是,
使用TextSwitcher也需要设置一个ViewFactory。与ImageSwitcher不同的是,TextSwitcher所需的
ViewFactory的makeView()必须返回一个TextView组件。
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent" >
7 <!-- 定义一个TextSwitcher,并指定了文本切换时的动画效果 -->
8 <TextSwitcher
9 android:id="@+id/textSwitcher"
10 android:layout_width="match_parent"
11 android:layout_height="wrap_content"
12 android:onClick="next"
13 android:inAnimation="@android:anim/slide_in_left"
14 android:outAnimation="@android:anim/slide_out_right" />
15 </LinearLayout>
1 public class TextSwitcherTest extends Activity {
2 TextSwitcher textSwitcher;
3 String[] strs = new String[] { "Android", "IOS", "JAVAEE", "PHP" };
4 int curStr;
5
6 @Override
7 public void onCreate(Bundle savedInstanceState) {
8 super.onCreate(savedInstanceState);
9 setContentView(R.layout.main);
10 textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher);
11 textSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
12 public View makeView() {
13 TextView tv = new TextView(TextSwitcherTest.this);
14 tv.setTextSize(40);
15 tv.setTextColor(Color.MAGENTA);
16 return tv;
17 }
18 });
19 // 调用next方法显示下一个字符串
20 next(null);
21 }
22
23 // 事件处理函数,控制显示下一个字符串
24 public void next(View source) {
25 textSwitcher.setText(strs[curStr++ % strs.length]);
26 }
27 }
上面的代码重写了ViewFactory的makeView(),该方法返回了一个TextView,这样即可让TextSwitcher
正常工作。当程序要切换TextSwitcher显示文本时,调用TextSwitcher的setText()方法修改文本即可。
★★★ ViewFlipper的功能与用法 ★★★
ViewFlipper继承了ViewAnimator,它可调用addView(View v)添加多个组件。一旦向ViewFlipper中添加
了多个组件之后,ViewFlipper可使用动画控制多个组件之间的切换效果。
ViewFlipper与前面介绍的AdapterViewFlipper有较大的相似性,它们可以控制组件切换的动画效果。
它们的区别是:
ViewFlipper需要开发者通过addView(View v)添加多个View;
AdapterViewFlipper则只要传入一个Adapter,Adapter将会负责提供多个View;
因此ViewFlipper可以指定与AdapterViewFlipper相同的XML属性。
范例:自动播放的图片库
1 <?xml version="1.0" encoding="utf-8"?>
2 <RelativeLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:orientation="vertical"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent">
7 <ViewFlipper
8 android:id="@+id/details"
9 android:layout_width="match_parent"
10 android:layout_height="match_parent"
11 android:persistentDrawingCache="animation"
12 android:flipInterval="1000">
13 <ImageView
14 android:src="@drawable/java"
15 android:layout_width="fill_parent"
16 android:layout_height="wrap_content" />
17 <ImageView
18 android:src="@drawable/android"
19 android:layout_width="fill_parent"
20 android:layout_height="wrap_content" />
21 <ImageView
22 android:src="@drawable/ee"
23 android:layout_width="fill_parent"
24 android:layout_height="wrap_content" />
25 </ViewFlipper>
26 <Button
27 android:text="<"
28 android:onClick="prev"
29 android:layout_width="wrap_content"
30 android:layout_height="wrap_content"
31 android:layout_alignParentBottom="true"
32 android:layout_alignParentLeft="true" />
33 <Button
34 android:layout_width="wrap_content"
35 android:layout_height="wrap_content"
36 android:layout_alignParentBottom="true"
37 android:layout_centerInParent="true"
38 android:onClick="auto"
39 android:text="自动播放" />
40 <Button
41 android:text=">"
42 android:onClick="next"
43 android:layout_width="wrap_content"
44 android:layout_height="wrap_content"
45 android:layout_alignParentBottom="true"
46 android:layout_alignParentRight="true" />
47 </RelativeLayout>
上面的布局文件定义了一个ViewFlipper,并在该ViewFlipper中定义了三个ImageView,这意味着该
ViewFlipper包含了三个子组件。接下来在Activity代码中即可调用ViewFlipper的showPrevious()、
showNext()等方法控制ViewFlipper显示上一个、下一个子组件。为了控制组件切换时的动画效果。
还需要调用ViewFlipper的setInAnimation()、setOutAnimation()方法设置动画效果。
1 public class ViewFlipperTest extends Activity {
2 private ViewFlipper viewFlipper;
3
4 @Override
5 public void onCreate(Bundle savedInstanceState) {
6 super.onCreate(savedInstanceState);
7 setContentView(R.layout.main);
8 viewFlipper = (ViewFlipper) findViewById(R.id.details);
9 }
10
11 public void prev(View source) {
12 viewFlipper.setInAnimation(this, R.anim.slide_in_right);
13 viewFlipper.setOutAnimation(this, R.anim.slide_out_left);
14 // 显示上一个组件
15 viewFlipper.showPrevious();
16 // 停止自动播放
17 viewFlipper.stopFlipping();
18 }
19
20 public void next(View source) {
21 viewFlipper.setInAnimation(this, android.R.anim.slide_in_left);
22 viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right);
23 // 显示下一个组件。
24 viewFlipper.showNext();
25 // 停止自动播放
26 viewFlipper.stopFlipping();
27 }
28
29 public void auto(View source) {
30 viewFlipper.setInAnimation(this, android.R.anim.slide_in_left);
31 viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right);
32 // 开始自动播放
33 viewFlipper.startFlipping();
34 }
35 }
二、Android应用的界面编程(七)ViewAnimator及其子类[ ViewSwitcher、ImageSwitcher、TextSwitcher、ViewFlipper ]
标签:
原文地址:http://www.cnblogs.com/androidsj/p/4601636.html