码迷,mamicode.com
首页 > 移动开发 > 详细

二、Android应用的界面编程(七)ViewAnimator及其子类[ ViewSwitcher、ImageSwitcher、TextSwitcher、ViewFlipper ]

时间:2015-06-26 10:49:30      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:

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="&lt;" />
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="&gt;" />
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="&lt;"
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="&gt;"
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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!