zoukankan      html  css  js  c++  java
  • 二、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>

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

  • 相关阅读:
    Java+Selenium——单选按钮操作
    Java+Selenium——如何点击菜单下子菜单
    java+selenium——打开多个窗口,并切换窗口——方法一
    Java+Selenium——处理Alert弹窗
    java+selenium——打开多个窗口,并切换窗口——方法三
    Java+Selenium——浏览器退出quit和close的区别
    c语言那些细节之littleendian和bigendian
    万能数据库查询分析器使用技巧之(九)
    人生顿悟之浮躁的心该静一静
    “万能数据库查询分析器”中英文4.01 已提交至国内几大软件下载网站,3日内就会发布,敬请期待
  • 原文地址:https://www.cnblogs.com/androidsj/p/4601636.html
Copyright © 2011-2022 走看看