喜糖

移动开发工程师 。涉及 android、ios、jni

导航

Android实现带动画效果的Tab Menu

Posted on 2011-09-19 15:44  喜糖  阅读(2115)  评论(0编辑  收藏  举报

大家好,今天给大家介绍如何在Android下实现一个带动画效果的Tab Menu。Tab Menu的打开动画效果为自下而上的淡入推进效果,关闭效果为自上而下的淡出推出效果。

实现的效果图如下(没有找到合适的屏幕录像工具,只能截静态图):

效果: 点击MENU键,系统的menu项是依次滑到界面上去的。

实现这个Tab可以替代android系统丑陋的menu界面,当用户点击menu按钮时,通过使用钩子函数onKeyDown(int keyCode, KeyEvent event)

实现思路:捕获menu按键事件,实现打开或者关闭Tab。当Tab打开后,按back按键会关闭Tab。

以下为关键代码,代码说明请看注释,完整工程代码下载请按此

TabMenuActivity.java

  1. package com.zhuozhuo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.KeyEvent;  
  6. import android.widget.TextView;  
  7.   
  8. public class TabMenuActivity extends Activity {  
  9.     /** Called when the activity is first created. */  
  10.       
  11.     TabView dockView;  
  12.     TextView tv;  
  13.       
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.main);  
  18.         tv = (TextView) findViewById(R.id.tv);  
  19.         dockView = new DockView(this);  
  20.     }  
  21.   
  22.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  23.         if (keyCode == KeyEvent.KEYCODE_MENU) {//监听menu键  
  24.             if(dockView.isOpen()) {  
  25.                 tv.setText("点击menu键打开dock");  
  26.                   
  27.                 dockView.closeDock();//关闭dock  
  28.             }  
  29.             else {  
  30.                 tv.setText("再次点击menu键或者back键关闭dock");  
  31.                 dockView.openDock();//打开dock  
  32.             }  
  33.             return true;  
  34.         }  
  35.         if (keyCode == KeyEvent.KEYCODE_BACK) {//监听back键  
  36.             if(dockView.isOpen()) {//当dock打开时,按back键关闭dock  
  37.                 dockView.closeDock();  
  38.                 return true;  
  39.             }  
  40.         }  
  41.         return super.onKeyDown(keyCode, event);  
  42.     }  
  43.       
  44.   
  45. }  

TabView.java

  1. package com.zhuozhuo;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.view.animation.Animation;  
  8. import android.view.animation.Animation.AnimationListener;  
  9. import android.view.animation.AnimationUtils;  
  10. import android.widget.Toast;  
  11.   
  12. public class TabView {  
  13.   
  14.     private static final int INTERVAL_TIME = 50;// 每个tab之间的动画时间间隔ms  
  15.   
  16.     private View tab1;  
  17.     private View tab2;  
  18.     private View tab3;  
  19.     private View tab4;  
  20.       
  21.     private Activity context;  
  22.       
  23.     private boolean isOpen;  
  24.   
  25.     public TabView(Activity context) {  
  26.         this.context = context;  
  27.         tab1 = context.findViewById(R.id.tab1);  
  28.         tab2 = context.findViewById(R.id.tab2);  
  29.         tab3 = context.findViewById(R.id.tab3);  
  30.         tab4 = context.findViewById(R.id.tab4);  
  31.         setOnClickListener(tab1, 1);  
  32.         setOnClickListener(tab2, 2);  
  33.         setOnClickListener(tab3, 3);  
  34.         setOnClickListener(tab4, 4);  
  35.     }  
  36.   
  37.     public void openDock() {//打开dock  
  38.         tab(tab1, 0true);  
  39.         tab(tab2, INTERVAL_TIME * 1true);  
  40.         tab(tab3, INTERVAL_TIME * 2true);  
  41.         tab(tab4, INTERVAL_TIME * 3true);  
  42.         isOpen = true;  
  43.     }  
  44.       
  45.     private void setOnClickListener(View view, final int pos) {  
  46.         view.setOnClickListener(new OnClickListener() {  
  47.               
  48.             @Override  
  49.             public void onClick(View v) {  
  50.                 Toast.makeText(context, "view" + pos + " click!", Toast.LENGTH_SHORT).show();//点击tab时显示toast  
  51.                 closeDock();  
  52.             }  
  53.         });  
  54.     }  
  55.       
  56.     private void tab(final View view,int delayTime,final boolean toOpen) {  
  57.         view.postDelayed(new Runnable() {  //延迟调用
  58.   
  59.             @Override  
  60.             public void run() {  
  61.                 Animation animation;  
  62.                   
  63.                 if(toOpen) {  
  64.                     view.setVisibility(View.VISIBLE);//动画开始前,设置view可见  
  65.                     animation = AnimationUtils.loadAnimation(context, R.anim.show_tab);  
  66.                     view.startAnimation(animation);  
  67.                       
  68.                 }  
  69.                 else {  
  70.                     animation = AnimationUtils.loadAnimation(context, R.anim.close_tab);  
  71.                     animation.setAnimationListener(new AnimationListener() {  
  72.                           
  73.                         @Override  
  74.                         public void onAnimationStart(Animation animation) {  
  75.                               
  76.                         }  
  77.                           
  78.                         @Override  
  79.                         public void onAnimationRepeat(Animation animation) {  
  80.                               
  81.                         }  
  82.                           
  83.                         @Override  
  84.                         public void onAnimationEnd(Animation animation) {  
  85.                             view.setVisibility(View.INVISIBLE);//动画结束时,view不可见  
  86.                               
  87.                         }  
  88.                     });  
  89.                     view.startAnimation(animation);  
  90.                       
  91.                       
  92.                 }  
  93.                   
  94.             }  
  95.         }, delayTime);  
  96.     }  
  97.       
  98.     public boolean isOpen() {  
  99.         return isOpen;  
  100.     }  
  101.   
  102.     public void closeDock() {//关闭dock  
  103.         tab(tab1, 0false);  
  104.         tab(tab2, INTERVAL_TIME * 1false);  
  105.         tab(tab3, INTERVAL_TIME * 2false);  
  106.         tab(tab4, INTERVAL_TIME * 3false);  
  107.         isOpen = false;  
  108.     }  
  109. }  


res/anim/close_tab.xml ,移动+显示

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="300"/>  
  4.     <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />  
  5. </set>  


res/anim/show_tab.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="300"/>  
  4.     <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />  
  5. </set>  

res/layout/main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.     <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" />  
  6.     <LinearLayout android:layout_height="wrap_content"  
  7.         android:layout_width="match_parent" android:layout_alignParentBottom="true">  
  8.         <LinearLayout android:layout_weight="1" android:id="@+id/tab1"  
  9.             android:layout_height="wrap_content" android:gravity="center"  
  10.             android:layout_width="wrap_content" android:orientation="vertical"  
  11.             android:visibility="invisible">  
  12.             <ImageView android:layout_width="wrap_content"  
  13.                 android:layout_height="wrap_content" android:src="@drawable/icon" />  
  14.             <TextView android:text="Tab1" android:layout_width="wrap_content"  
  15.                 android:layout_height="wrap_content" />  
  16.         </LinearLayout>  
  17.         <LinearLayout android:layout_weight="1" android:id="@+id/tab2"  
  18.             android:layout_height="wrap_content" android:layout_width="wrap_content"  
  19.             android:gravity="center" android:orientation="vertical"  
  20.             android:visibility="invisible">  
  21.             <ImageView android:layout_width="wrap_content"  
  22.                 android:layout_height="wrap_content" android:src="@drawable/icon" />  
  23.             <TextView android:text="Tab1" android:layout_width="wrap_content"  
  24.                 android:layout_height="wrap_content" />  
  25.         </LinearLayout>  
  26.         <LinearLayout android:layout_weight="1" android:id="@+id/tab3"  
  27.             android:layout_height="wrap_content" android:layout_width="wrap_content"  
  28.             android:gravity="center" android:orientation="vertical"  
  29.             android:visibility="invisible">  
  30.             <ImageView android:layout_width="wrap_content"  
  31.                 android:layout_height="wrap_content" android:src="@drawable/icon" />  
  32.             <TextView android:text="Tab1" android:layout_width="wrap_content"  
  33.                 android:layout_height="wrap_content" />  
  34.         </LinearLayout>  
  35.         <LinearLayout android:layout_weight="1" android:id="@+id/tab4"  
  36.             android:layout_height="wrap_content" android:layout_width="wrap_content"  
  37.             android:gravity="center" android:orientation="vertical"  
  38.             android:visibility="invisible">  
  39.             <ImageView android:layout_width="wrap_content"  
  40.                 android:layout_height="wrap_content" android:src="@drawable/icon" />  
  41.             <TextView android:text="Tab1" android:layout_width="wrap_content"  
  42.                 android:layout_height="wrap_content" />  
  43.         </LinearLayout>  
  44.     </LinearLayout>  
  45. </RelativeLayout>