现在的位置: 首页 > 综合 > 正文

ViewSwitcher实现程序列表分屏和动画效果

2012年12月14日 ⁄ 综合 ⁄ 共 4386字 ⁄ 字号 评论关闭

  Android的Launcher界面功能菜单是一个列表,当应用程序较多时,可以向下滑动查看其它,如下图。那能不能将功能菜单做成横向拖动,并且分屏的效果呢?



    本文对该问题进行研究,要达到的目标如下:

    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) { 

抱歉!评论已关闭.