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

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>

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

★★★ 图片切换器(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 }

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

★★★ 文本切换器(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 ]

 

你可能感兴趣的:(ImageSwitcher)