zoukankan      html  css  js  c++  java
  • ViewSwitch

    一、结构

    public class ViewSwitcher extends ViewAnimator

            

    java.lang.Object

    android.view.View

             android.view.ViewGroup

                       android.widget.FrameLayout

                                android.widget.ViewAnimator

                                         android.widget.ViewSwitcher

     已知直接子类

    ImageSwitcherTextSwitcher

    二、概述

         在两个视图间转换时显示动画,有一个可以创建这些视图的工厂类。你可以用工厂来创建这些视图,也可以自己创建。一个ViewSwitcher只允许包含两个子视图,且一次仅能显示一个。

      (译者注:与ViewFlipper类相似,但该类不常用,常用其两个子类ImageSwitcher:转换图片时增加动画效果TextSwitcher 转换文字时增加动画效果其实例见apidemosImageSwitcher实例和TextSwitcher实例

    三、内部类

        interface          ViewSwitcher.ViewFactory     

        在一个ViewSwitcher里创建视图

    公共方法

      public void addView(View child, int index, ViewGroup.LayoutParams params)

            添加一个指定布局参数的子视图

                参数

      child         添加的子视图

      index       添加的子视图的索引

      params    子视图的布局参数

      异常

      IllegalStateException       如果切换器中已经包含了两个视图时。

       

      public View getNextView ()

      返回下一个要显示的视图

      视图切换之后将要显示出的下一个视图

     

      public void reset ()

      重置视图转换器(ViewSwitcher)来隐藏所有存在的视图,并使转换器达到一次动画都还没有播放的状态。

     

      public void setFactory (ViewSwitcher.ViewFactory factory)

      设置用来生成将在视图转换器中切换的两个视图的工厂。也可以调用两次 addView(android.view.View, int, android.view.ViewGroup.LayoutParams)来替代使用工厂的方法。

      参数

      factory   用来生成转换器内容的视图工厂

     

    1、可以实现应用程序的分屏显示,当一屏放不下时,放入另一个屏。
    2、屏与屏之间切换为横向。
    3、屏与屏之间切换时有动画效果,一个屏退出,一个屏出现。

    分屏和横向显示不是很难解决的问题,关键问题在于动画效果的实现。由于在屏幕切换时两个屏同时发生动画,一个退出,一个进入,因此至少要同时存在两个View。实际上Android已经为我们考虑了这种情况。ViewSwitcher就是专门针对这种情况而设计的。
        ViewSwitcher内部保存了两个View,通过我们的控制可以显示前一个和后一个,并且我们可以设置在切换中两个View的动画。View的生成为ViewFactory生成。该类还是比较简单的,需要详细研究参考google文档和源代码。
    多的不说,上代码吧。
        首先我们模拟一下功能菜单的数据部分,也就是分几个屏,每个屏有哪些应用之类的东西。注释较多,不多解释。

    1. /** 
    2. * 该类模拟了功能菜单的数据部分 
    3. */ 
    4. public class MenuData { 
    5.     /**该常量代表每一屏能够容纳的应用程序数目*/ 
    6.     public static final int NUMBER_IN_ONE_SCREEN = 9
    7.      
    8.     /**该类代表每个应用程序的数据部分*/ 
    9.     public static class DataItem { 
    10.         public String dataName;   //应用程序名称 
    11.         public Drawable drawable;  //应用程序图标 
    12.     } 
    13.      
    14.     /**该类代表了一个屏的所有应用程序*/ 
    15.     public static class MenuDataOneScreen {  
    16.         ArrayList<DataItem> mDataItems = new ArrayList<DataItem>(); 
    17.     } 
    18.      
    19.     /**该数据时该类的主要部分,所有屏的列表,实际上该类就是代表了所有的屏*/ 
    20.     ArrayList<MenuDataOneScreen> mScreens = new ArrayList<MenuDataOneScreen>(); 
    21.      
    22.     /**对该类进行赋予数据*/ 
    23.     public void setMenuItems(ArrayList<DataItem> dataItems) { 
    24.         int screenNum = dataItems.size() / NUMBER_IN_ONE_SCREEN; 
    25.         int remain = dataItems.size() % NUMBER_IN_ONE_SCREEN; 
    26.         screenNum += remain == 0 ? 0 : 1
    27.          
    28.         int pos = 0
    29.         for (int i = 0; i < screenNum; i++) { 
    30.             MenuDataOneScreen screen = new MenuDataOneScreen(); 
    31.             for (int j = 0; j < NUMBER_IN_ONE_SCREEN; j++) { 
    32.                 if (pos <= dataItems.size() - 1) { 
    33.                     screen.mDataItems.add(dataItems.get(pos)); 
    34.                     pos++; 
    35.                 } 
    36.             } 
    37.             mScreens.add(screen); 
    38.         } 
    39.     } 
    40.      
    41.     /**获取屏的数目*/ 
    42.     public int getScreenNumber() { 
    43.         return mScreens.size(); 
    44.     } 
    45.      
    46.     /**根据屏的索引,获取某个屏的数据*/ 
    47.     public MenuDataOneScreen getScreen(int screenIndex) { 
    48.         return mScreens.get(screenIndex); 
    49.     } 

        然后,我们重载ViewFactory类,定义我们如何生成View,生成什么样的View。

    1. public class SlideViewFactory implements ViewFactory{ 
    2.     LayoutInflater mInflater; 
    3.     public SlideViewFactory(Context context) { 
    4.         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    5.     } 
    6.      
    7.     /**这个函数就是得到我们要生成的View,这里实际上直接从布局得到, 
    8.     *我们定义的是一个GridView ,一个GridView用于显示一屏的应用程序*/  
    9.     public View makeView() { 
    10.         return mInflater.inflate(R.layout.slidelistview, null); 
    11.     } 

        从上面的代码我们可以看出,我们生成的View实际是一个GridView,GridView要想和数据关联,则需要一个Adapter,因此我们下面定义该Adapter:

    1. public class OneScreenListAdapter extends BaseAdapter{ 
    2.     private MenuDataOneScreen mScreen; 
    3.     private LayoutInflater mInflater; 
    4.      
    5.     public OneScreenListAdapter(Context context) { 
    6.         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    7.     } 
    8.      
    9.     /**这里将数据赋予Adapter*/ 
    10.     public void setScreenData(MenuDataOneScreen screenData) { 
    11.         mScreen = screenData
    12.     } 
    13.  
    14.     public int getCount() { 
    15.         return mScreen.mDataItems.size(); 
    16.     } 
    17.  
    18.     public Object getItem(int position) { 
    19.         return mScreen.mDataItems.get(position); 
    20.     } 
    21.  
    22.     public long getItemId(int position) { 
    23.         return position; 
    24.     } 
    25.  
    26.     /**该函数中将数据和View进行关联*/ 
    27.     public View getView(int position, View convertView, ViewGroup parent) { 
    28.         View view = convertView
    29.         if (convertView == null) { 
    30.             view = mInflater.inflate(R.layout.labelicon, null); 
    31.         }  
    32.      
    33.         ImageView imageView = (ImageView) view.findViewById(R.id.imageview); 
    34.         TextView textView = (TextView) view.findViewById(R.id.textview); 
    35.         imageView.setImageDrawable(mScreen.mDataItems.get(position).drawable); 
    36.         textView.setText(mScreen.mDataItems.get(position).dataName); 
    37.          
    38.         return view; 
    39.     } 
    40.  

        下面是继承ViewSwitcher的部分,用来实现两个屏的切换。

    1. /**该部分是ViewSwitcher的重载,用该类实现两个屏的切换和切换的动画实现*/ 
    2. public class SlideMenuSwitcher extends ViewSwitcher{ 
    3.     private MenuData mMenuData; 
    4.     private int mCurrentScreen; 
    5.     private Context mContext; 
    6.      
    7.     public SlideMenuSwitcher(Context context, AttributeSet attrs) { 
    8.         super(context, attrs); 
    9.         setFactory(new SlideViewFactory(context)); 
    10. //      setAnimateFirstView(false); 
    11.         mContext = context
    12.     } 
    13.      
    14.     /**通过该方法将数据赋值进去,并且将初始的屏显示出来*/ 
    15.     public void setData(ArrayList<DataItem> dataItems) { 
    16.         mMenuData = new MenuData(); 
    17.         mMenuData.setMenuItems(dataItems); 
    18.         mCurrentScreen = mMenuData.getScreenNumber() / 2; 
    19.          
    20.         GridView listView = (GridView) getCurrentView(); 
    21.         OneScreenListAdapter adapter = new OneScreenListAdapter(mContext); 
    22.         adapter.setScreenData(mMenuData.getScreen(mCurrentScreen)); 
    23.         listView.setAdapter(adapter); 
    24.     } 
    25.      
    26.     /**该方法用于显示下一屏*/ 
    27.     public void showNextScreen() { 
    28.         if (mCurrentScreen < mMenuData.getScreenNumber() - 1) { 
    29.             mCurrentScreen++; 
    30.             setInAnimation(mContext, R.anim.slide_in_right); 
    31.             setOutAnimation(mContext, R.anim.slide_out_left); 
    32.         } else { 
    33.             return; 
    34.         } 
    35.          
    36.         setViewData(mCurrentScreen); 
    37.         showNext(); 
    38.     } 
    39.      
    40.     /**该方法用于显示上一屏*/ 
    41.     public void showPreviousScreen() { 
    42.         if (mCurrentScreen > 0) { 
    43.             mCurrentScreen--; 
    44.             setInAnimation(mContext, R.anim.slide_in_left); 
    45.             setOutAnimation(mContext, R.anim.slide_out_right); 
    46.         } else { 
    47.             return; 
    48.         } 
    49.          
    50.         setViewData(mCurrentScreen); 
    51.         showPrevious(); 
    52.     } 
    53.      
    54.     private void setViewData(int index) { 
    55.         GridView listView = (GridView) getNextView(); 
    56.         OneScreenListAdapter adapter = new OneScreenListAdapter(mContext); 
    57.         adapter.setScreenData(mMenuData.getScreen(index)); 
    58.         listView.setAdapter(adapter); 
    59.     } 
    60.  

        我们将在一个Activity中,将我们做好的东西实现。首先在布局中将我们写的SlideMenuSwitcher。

    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    2.     android:layout_width="fill_parent" 
    3.     android:layout_height="fill_parent" 
    4.     > 
    5.     <com.winuxxan.SlideMenu.SlideMenuSwitcher 
    6.         android:id="@+id/slide_view" 
    7.         android:layout_width="fill_parent" 
    8.         android:layout_height="fill_parent" 
    9.     /> 
    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:text="&lt;--" 
    18.     /> 
    19.     <Button 
    20.         android:id="@+id/button_next" 
    21.         android:layout_width="wrap_content" 
    22.         android:layout_height="wrap_content" 
    23.         android:layout_alignParentBottom="true" 
    24.         android:layout_alignParentRight="true" 
    25.         android:text="--&gt;" 
    26.     /> 
    27. </RelativeLayout> 

        最后,实现我们的Activity:

    1. public class SlideMenuActivity extends Activity { 
    2.     /** Called when the activity is first created. */ 
    3.     SlideMenuSwitcher switcher; 
    4.     @Override 
    5.     public void onCreate(Bundle savedInstanceState) { 
    6.         super.onCreate(savedInstanceState); 
    7.         setContentView(R.layout.main); 
    8.         switcher = (SlideMenuSwitcher) findViewById(R.id.slide_view); 
    9.         switcher.setData(makeItems());    //将24个应用程序赋值到swithcer中。 
    10.          
    11.         findViewById(R.id.button_next).setOnClickListener(new OnClickListener() { 
    12.              
    13.             public void onClick(View v) { 
    14.                 switcher.showNextScreen();  //点击右边按钮,显示下一屏,当然可以采用手势 
    15.             } 
    16.         }); 
    17.          
    18.         findViewById(R.id.button_prev).setOnClickListener(new OnClickListener() { 
    19.              
    20.             public void onClick(View v) { 
    21.                 switcher.showPreviousScreen();  //点击左边按钮,显示上一屏,当然可以采用手势 
    22.  
    23.             } 
    24.         }); 
    25.     } 
    26.      
    27.     /**模拟24个应用程序*/ 
    28.     private ArrayList<DataItem> makeItems() { 
    29.         ArrayList<DataItem> items = new ArrayList<DataItem>(); 
    30.         for (int i = 0; i < 24; i++) { 
    31.             String label = "" + i; 
    32.             Drawable drawable = getResources().getDrawable(R.drawable.icon); 
    33.             DataItem item = new DataItem(); 
    34.             item.dataName = label; 
    35.             item.drawable = drawable; 
    36.             items.add(item); 
    37.         } 
    38.          
    39.         return items; 
    40.     } 

        好了,运行我们的应用程序,看下,效果是否是我们想要的?(动画效果没法抓图)

     

  • 相关阅读:
    python版本切换及添加路径
    python下载及安装步骤
    day01计算机基础-python解释器-pycharm介绍
    查看pycharm有效期
    对于Makefile的基本使用
    Shell命令整理
    一起来免费听无损高品质音乐吧!
    记录 解决ubuntu16.04 ‘E: 无法获得锁 /var/lib/dpkg/lock-frontend
    Ubuntu16手动安装OpenStack——keystone篇
    python3中的RE(正则表达式)
  • 原文地址:https://www.cnblogs.com/lyz459/p/2575896.html
Copyright © 2011-2022 走看看