Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android一分鐘實現滑動菜單特效

Android一分鐘實現滑動菜單特效

編輯:Android開發實例

之前我向大家介紹了史上最簡單的滑動菜單的實現方式,相信大家都還記得。如果忘記了其中的實現原理或者還沒看過的朋友,請先去看一遍之前的文章 http://www.fengfly.com/plus/view-215082-1.html,因為我們今天要實現的滑動菜單框架也是基於同樣的原理的。

之前的文章中在最後也提到了,如果是你的應用程序中有很多個Activity都需要加入滑動菜單的功能,那麼每個Activity都要寫上百行的代碼才能實現效果,再簡單的滑動菜單實現方案也沒用。因此我們今天要實現一個滑動菜單的框架,然後在任何Activity中都可以一分鐘引入滑動菜單功能。

首先還是講一下實現原理。說是滑動菜單的框架,其實說白了也很簡單,就是我們自定義一個布局,在這個自定義布局中實現好滑動菜單的功能,然後只要在Activity的布局文件裡面引入我們自定義的布局,這個Activity就擁有了滑動菜單的功能了。原理講完了,是不是很簡單?下面我們來動手實現吧。

在Eclipse中新建一個Android項目,項目名就叫做RenRenSlidingLayout。

新建一個類,名叫SlidingLayout,這個類是繼承自LinearLayout的,並且實現了OnTouchListener接口,具體代碼如下:

  1. public class SlidingLayout extends LinearLayout implements OnTouchListener {  
  2.  
  3.     /**  
  4.      * 滾動顯示和隱藏左側布局時,手指滑動需要達到的速度。  
  5.      */ 
  6.     public static final int SNAP_VELOCITY = 200;  
  7.  
  8.     /**  
  9.      * 屏幕寬度值。  
  10.      */ 
  11.     private int screenWidth;  
  12.  
  13.     /**  
  14.      * 左側布局最多可以滑動到的左邊緣。值由左側布局的寬度來定,marginLeft到達此值之後,不能再減少。  
  15.      */ 
  16.     private int leftEdge;  
  17.  
  18.     /**  
  19.      * 左側布局最多可以滑動到的右邊緣。值恆為0,即marginLeft到達0之後,不能增加。  
  20.      */ 
  21.     private int rightEdge = 0;  
  22.  
  23.     /**  
  24.      * 左側布局完全顯示時,留給右側布局的寬度值。  
  25.      */ 
  26.     private int leftLayoutPadding = 80;  
  27.  
  28.     /**  
  29.      * 記錄手指按下時的橫坐標。  
  30.      */ 
  31.     private float xDown;  
  32.  
  33.     /**  
  34.      * 記錄手指移動時的橫坐標。  
  35.      */ 
  36.     private float xMove;  
  37.  
  38.     /**  
  39.      * 記錄手機抬起時的橫坐標。  
  40.      */ 
  41.     private float xUp;  
  42.  
  43.     /**  
  44.      * 左側布局當前是顯示還是隱藏。只有完全顯示或隱藏時才會更改此值,滑動過程中此值無效。  
  45.      */ 
  46.     private boolean isLeftLayoutVisible;  
  47.  
  48.     /**  
  49.      * 左側布局對象。  
  50.      */ 
  51.     private View leftLayout;  
  52.  
  53.     /**  
  54.      * 右側布局對象。  
  55.      */ 
  56.     private View rightLayout;  
  57.  
  58.     /**  
  59.      * 用於監聽側滑事件的View。  
  60.      */ 
  61.     private View mBindView;  
  62.  
  63.     /**  
  64.      * 左側布局的參數,通過此參數來重新確定左側布局的寬度,以及更改leftMargin的值。  
  65.      */ 
  66.     private MarginLayoutParams leftLayoutParams;  
  67.  
  68.     /**  
  69.      * 右側布局的參數,通過此參數來重新確定右側布局的寬度。  
  70.      */ 
  71.     private MarginLayoutParams rightLayoutParams;  
  72.  
  73.     /**  
  74.      * 用於計算手指滑動的速度。  
  75.      */ 
  76.     private VelocityTracker mVelocityTracker;  
  77.  
  78.     /**  
  79.      * 重寫SlidingLayout的構造函數,其中獲取了屏幕的寬度。  
  80.      *   
  81.      * @param context  
  82.      * @param attrs  
  83.      */ 
  84.     public SlidingLayout(Context context, AttributeSet attrs) {  
  85.         super(context, attrs);  
  86.         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  
  87.         screenWidth = wm.getDefaultDisplay().getWidth();  
  88.     }  
  89.  
  90.     /**  
  91.      * 綁定監聽側滑事件的View,即在綁定的View進行滑動才可以顯示和隱藏左側布局。  
  92.      *   
  93.      * @param bindView  
  94.      *            需要綁定的View對象。  
  95.      */ 
  96.     public void setScrollEvent(View bindView) {  
  97.         mBindView = bindView;  
  98.         mBindView.setOnTouchListener(this);  
  99.     }  
  100.  
  101.     /**  
  102.      * 將屏幕滾動到左側布局界面,滾動速度設定為30.  
  103.      */ 
  104.     public void scrollToLeftLayout() {  
  105.         new ScrollTask().execute(30);  
  106.     }  
  107.  
  108.     /**  
  109.      * 將屏幕滾動到右側布局界面,滾動速度設定為-30.  
  110.      */ 
  111.     public void scrollToRightLayout() {  
  112.         new ScrollTask().execute(-30);  
  113.     }  
  114.  
  115.     /**  
  116.      * 左側布局是否完全顯示出來,或完全隱藏,滑動過程中此值無效。  
  117.      *   
  118.      * @return 左側布局完全顯示返回true,完全隱藏返回false。  
  119.      */ 
  120.     public boolean isLeftLayoutVisible() {  
  121.         return isLeftLayoutVisible;  
  122.     }  
  123.  
  124.     /**  
  125.      * 在onLayout中重新設定左側布局和右側布局的參數。  
  126.      */ 
  127.     @Override 
  128.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  129.         super.onLayout(changed, l, t, r, b);  
  130.         if (changed) {  
  131.             // 獲取左側布局對象  
  132.             leftLayout = getChildAt(0);  
  133.             leftLayoutParams = (MarginLayoutParams) leftLayout.getLayoutParams();  
  134.             // 重置左側布局對象的寬度為屏幕寬度減去leftLayoutPadding  
  135.             leftLayoutParams.width = screenWidth - leftLayoutPadding;  
  136.             // 設置最左邊距為負的左側布局的寬度  
  137.             leftEdge = -leftLayoutParams.width;  
  138.             leftLayoutParams.leftMargin = leftEdge;  
  139.             leftLayout.setLayoutParams(leftLayoutParams);  
  140.             // 獲取右側布局對象  
  141.             rightLayout = getChildAt(1);  
  142.             rightLayoutParams = (MarginLayoutParams) rightLayout.getLayoutParams();  
  143.             rightLayoutParams.width = screenWidth;  
  144.             rightLayout.setLayoutParams(rightLayoutParams);  
  145.         }  
  146.     }  
  147.  
  148.     @Override 
  149.     public boolean onTouch(View v, MotionEvent event) {  
  150.         createVelocityTracker(event);  
  151.         switch (event.getAction()) {  
  152.         case MotionEvent.ACTION_DOWN:  
  153.             // 手指按下時,記錄按下時的橫坐標  
  154.             xDown = event.getRawX();  
  155.             break;  
  156.         case MotionEvent.ACTION_MOVE:  
  157.             // 手指移動時,對比按下時的橫坐標,計算出移動的距離,來調整左側布局的leftMargin值,從而顯示和隱藏左側布局  
  158.             xMove = event.getRawX();  
  159.             int distanceX = (int) (xMove - xDown);  
  160.             if (isLeftLayoutVisible) {  
  161.                 leftLayoutParams.leftMargin = distanceX;  
  162.             } else {  
  163.                 leftLayoutParams.leftMargin = leftEdge + distanceX;  
  164.             }  
  165.             if (leftLayoutParams.leftMargin < leftEdge) {  
  166.                 leftLayoutParams.leftMargin = leftEdge;  
  167.             } else if (leftLayoutParams.leftMargin > rightEdge) {  
  168.                 leftLayoutParams.leftMargin = rightEdge;  
  169.             }  
  170.             leftLayout.setLayoutParams(leftLayoutParams);  
  171.             break;  
  172.         case MotionEvent.ACTION_UP:  
  173.             // 手指抬起時,進行判斷當前手勢的意圖,從而決定是滾動到左側布局,還是滾動到右側布局  
  174.             xUp = event.getRawX();  
  175.             if (wantToShowLeftLayout()) {  
  176.                 if (shouldScrollToLeftLayout()) {  
  177.                     scrollToLeftLayout();  
  178.                 } else {  
  179.                     scrollToRightLayout();  
  180.                 }  
  181.             } else if (wantToShowRightLayout()) {  
  182.                 if (shouldScrollToContent()) {  
  183.                     scrollToRightLayout();  
  184.                 } else {  
  185.                     scrollToLeftLayout();  
  186.                 }  
  187.             }  
  188.             recycleVelocityTracker();  
  189.             break;  
  190.         }  
  191.         return isBindBasicLayout();  
  192.     }  
  193.  
  194.     /**  
  195.      * 判斷當前手勢的意圖是不是想顯示右側布局。如果手指移動的距離是負數,且當前左側布局是可見的,則認為當前手勢是想要顯示右側布局。  
  196.      *   
  197.      * @return 當前手勢想顯示右側布局返回true,否則返回false。  
  198.      */ 
  199.     private boolean wantToShowRightLayout() {  
  200.         return xUp - xDown < 0 && isLeftLayoutVisible;  
  201.     }  
  202.  
  203.     /**  
  204.      * 判斷當前手勢的意圖是不是想顯示左側布局。如果手指移動的距離是正數,且當前左側布局是不可見的,則認為當前手勢是想要顯示左側布局。  
  205.      *   
  206.      * @return 當前手勢想顯示左側布局返回true,否則返回false。  
  207.      */ 
  208.     private boolean wantToShowLeftLayout() {  
  209.         return xUp - xDown > 0 && !isLeftLayoutVisible;  
  210.     }  
  211.  
  212.     /**  
  213.      * 判斷是否應該滾動將左側布局展示出來。如果手指移動距離大於屏幕的1/2,或者手指移動速度大於SNAP_VELOCITY,  
  214.      * 就認為應該滾動將左側布局展示出來。  
  215.      *   
  216.      * @return 如果應該滾動將左側布局展示出來返回true,否則返回false。  
  217.      */ 
  218.     private boolean shouldScrollToLeftLayout() {  
  219.         return xUp - xDown > screenWidth / 2 || getScrollVelocity() > SNAP_VELOCITY;  
  220.     }  
  221.  
  222.     /**  
  223.      * 判斷是否應該滾動將右側布局展示出來。如果手指移動距離加上leftLayoutPadding大於屏幕的1/2,  
  224.      * 或者手指移動速度大於SNAP_VELOCITY, 就認為應該滾動將右側布局展示出來。  
  225.      *   
  226.      * @return 如果應該滾動將右側布局展示出來返回true,否則返回false。  
  227.      */ 
  228.     private boolean shouldScrollToContent() {  
  229.         return xDown - xUp + leftLayoutPadding > screenWidth / 2 
  230.                 || getScrollVelocity() > SNAP_VELOCITY;  
  231.     }  
  232.  
  233.     /**  
  234.      * 判斷綁定滑動事件的View是不是一個基礎layout,不支持自定義layout,只支持四種基本layout,  
  235.      * AbsoluteLayout已被棄用。  
  236.      *   
  237.      * @return 如果綁定滑動事件的View是LinearLayout,RelativeLayout,FrameLayout,  
  238.      *         TableLayout之一就返回true,否則返回false。  
  239.      */ 
  240.     private boolean isBindBasicLayout() {  
  241.         if (mBindView == null) {  
  242.             return false;  
  243.         }  
  244.         String viewName = mBindView.getClass().getName();  
  245.         return viewName.equals(LinearLayout.class.getName())  
  246.                 || viewName.equals(RelativeLayout.class.getName())  
  247.                 || viewName.equals(FrameLayout.class.getName())  
  248.                 || viewName.equals(TableLayout.class.getName());  
  249.     }  
  250.  
  251.     /**  
  252.      * 創建VelocityTracker對象,並將觸摸事件加入到VelocityTracker當中。  
  253.      *   
  254.      * @param event  
  255.      *            右側布局監聽控件的滑動事件  
  256.      */ 
  257.     private void createVelocityTracker(MotionEvent event) {  
  258.         if (mVelocityTracker == null) {  
  259.             mVelocityTracker = VelocityTracker.obtain();  
  260.         }  
  261.         mVelocityTracker.addMovement(event);  
  262.     }  
  263.  
  264.     /**  
  265.      * 獲取手指在右側布局的監聽View上的滑動速度。  
  266.      *   
  267.      * @return 滑動速度,以每秒鐘移動了多少像素值為單位。  
  268.      */ 
  269.     private int getScrollVelocity() {  
  270.         mVelocityTracker.computeCurrentVelocity(1000);  
  271.         int velocity = (int) mVelocityTracker.getXVelocity();  
  272.         return Math.abs(velocity);  
  273.     }  
  274.  
  275.     /**  
  276.      * 回收VelocityTracker對象。  
  277.      */ 
  278.     private void recycleVelocityTracker() {  
  279.         mVelocityTracker.recycle();  
  280.         mVelocityTracker = null;  
  281.     }  
  282.  
  283.     class ScrollTask extends AsyncTask<Integer, Integer, Integer> {  
  284.  
  285.         @Override 
  286.         protected Integer doInBackground(Integer... speed) {  
  287.             int leftMargin = leftLayoutParams.leftMargin;  
  288.             // 根據傳入的速度來滾動界面,當滾動到達左邊界或右邊界時,跳出循環。  
  289.             while (true) {  
  290.                 leftMargin = leftMargin + speed[0];  
  291.                 if (leftMargin > rightEdge) {  
  292.                     leftMargin = rightEdge;  
  293.                     break;  
  294.                 }  
  295.                 if (leftMargin < leftEdge) {  
  296.                     leftMargin = leftEdge;  
  297.                     break;  
  298.                 }  
  299.                 publishProgress(leftMargin);  
  300.                 // 為了要有滾動效果產生,每次循環使線程睡眠20毫秒,這樣肉眼才能夠看到滾動動畫。  
  301.                 sleep(20);  
  302.             }  
  303.             if (speed[0] > 0) {  
  304.                 isLeftLayoutVisible = true;  
  305.             } else {  
  306.                 isLeftLayoutVisible = false;  
  307.             }  
  308.             return leftMargin;  
  309.         }  
  310.  
  311.         @Override 
  312.         protected void onProgressUpdate(Integer... leftMargin) {  
  313.             leftLayoutParams.leftMargin = leftMargin[0];  
  314.             leftLayout.setLayoutParams(leftLayoutParams);  
  315.         }  
  316.  
  317.         @Override 
  318.         protected void onPostExecute(Integer leftMargin) {  
  319.             leftLayoutParams.leftMargin = leftMargin;  
  320.             leftLayout.setLayoutParams(leftLayoutParams);  
  321.         }  
  322.     }  
  323.  
  324.     /**  
  325.      * 使當前線程睡眠指定的毫秒數。  
  326.      *   
  327.      * @param millis  
  328.      *            指定當前線程睡眠多久,以毫秒為單位  
  329.      */ 
  330.     private void sleep(long millis) {  
  331.         try {  
  332.             Thread.sleep(millis);  
  333.         } catch (InterruptedException e) {  
  334.             e.printStackTrace();  
  335.         }  
  336.     }  
  337. }  

看到這裡,我相信大家一定會覺得這些代碼非常熟悉。沒錯,基本上這些代碼和之前那篇文章的代碼大同小異,只不過以前這些代碼是寫在Activity裡的,而現在我們移動到了自定義的View當中。

 

接著我來說明一下和以前不同的部分。我們可以看到,這裡將onLayout方法進行了重寫,使用getChildAt(0)獲取到的布局作為左邊布局,使用getChildAt(1)獲取到的布局作為右邊布局。並將左邊布局的寬度重定義為屏幕寬度減去leftLayoutPadding,將右側布局的寬度重定義為屏幕寬度。然後讓左邊布局偏移出屏幕,這樣能看到的就只有右邊布局了。因此在這裡我們也可以看出,使用SlidingLayout這個布局的前提條件,必須為這個布局提供兩個子元素,第一個元素會作為左邊布局偏移出屏幕,第二個元素會作為右邊布局顯示在屏幕上。

然後我們看一下setScrollEvent方法,這個方法接收一個View作為參數,然後為這個View綁定了一個touch事件。這是什麼意思呢?讓我們來想象一個場景,如果右側布局是一個LinearLayout,我可以通過監聽LinearLayout上的touch事件來控制左側布局的顯示和隱藏。但是如果右側布局的LinearLayout裡面加入了一個ListView,而這個ListView又充滿了整個LinearLayout,這個時候LinearLayout將不可能再被touch到了,這個時候我們就需要將touch事件注冊到ListView上。setScrollEvent方法也就是提供了一個注冊接口,touch事件將會注冊到傳入的View上。

最後還有一個陌生的方法,isBindBasicLayout。這個方法就是判斷了一下注冊touch事件的View是不是四個基本布局之一,如果是就返回true,否則返回false。這個方法在整個SlidingLayout中起著非常重要的作用,主要用於控制onTouch事件是返回true還是false,這將影響到布局當中的View的功能是否可用。由於裡面牽扯到了Android的事件轉發機制,內容比較多,就不在這裡詳細解釋了,我會考慮以後專門寫一篇文章來介紹Android的事件機制。這裡就先簡單記住如果是基本布局就返回true,否則就返回false。

好了,我們的SlidingLayout寫完了,接下來就是見證奇跡的時刻,讓我們一起看看如何一分鐘在Activity中引入滑動菜單功能。

創建或打開layout目錄下的activity_main.xml文件,加入如下代碼:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     xmlns:tools="http://schemas.android.com/tools" 
  3.     android:layout_width="fill_parent" 
  4.     android:layout_height="fill_parent" 
  5.     android:orientation="horizontal" 
  6.     tools:context=".MainActivity" > 
  7.  
  8.     <!-- 使用自定義的側滑布局,orientation必須為水平方向 --> 
  9.  
  10.     <com.example.slide.SlidingLayout 
  11.         android:id="@+id/slidingLayout" 
  12.         android:layout_width="fill_parent" 
  13.         android:layout_height="fill_parent" 
  14.         android:orientation="horizontal" > 
  15.  
  16.         <!--  
  17.             側滑布局的根節點下,有且只能有兩個子元素,這兩個子元素必須是四種基本布局之一,  
  18.             即LinearLayout, RelativeLayout, FrameLayout或TableLayout。  
  19.             第一個子元素將做為左側布局,初始化後被隱藏。第二個子元素將做為右側布局,  
  20.             也就是當前Activity的主布局,將主要的數據放在裡面。  
  21.         --> 
  22.  
  23.         <RelativeLayout 
  24.             android:id="@+id/menu" 
  25.             android:layout_width="fill_parent" 
  26.             android:layout_height="fill_parent" 
  27.             android:background="#00ccff" > 
  28.  
  29.             <TextView 
  30.                 android:layout_width="wrap_content" 
  31.                 android:layout_height="wrap_content" 
  32.                 android:layout_centerInParent="true" 
  33.                 android:text="This is menu" 
  34.                 android:textColor="#000000" 
  35.                 android:textSize="28sp" /> 
  36.         </RelativeLayout> 
  37.  
  38.         <LinearLayout 
  39.             android:id="@+id/content" 
  40.             android:layout_width="fill_parent" 
  41.             android:layout_height="fill_parent" 
  42.             android:orientation="vertical" > 
  43.  
  44.             <Button 
  45.                 android:id="@+id/menuButton" 
  46.                 android:layout_width="wrap_content" 
  47.                 android:layout_height="wrap_content" 
  48.                 android:text="Menu" /> 
  49.  
  50.             <ListView 
  51.                 android:id="@+id/contentList" 
  52.                 android:layout_width="fill_parent" 
  53.                 android:layout_height="fill_parent" > 
  54.             </ListView> 
  55.         </LinearLayout> 
  56.     </com.example.slide.SlidingLayout> 
  57.  
  58. </LinearLayout> 

我們可以看到,在根布局的下面,我們引入了自定義布局com.example.slide.SlidingLayout,然後在它裡面加入了兩個子元素,一個RelativeLayout和一個LinearLayout。RelativeLayout中比較簡單,就加入了一個TextView。LinearLayout裡面我們加入了一個按鈕和一個ListView。

 

然後創建或打開MainActivity作為程序的主Activity,加入代碼:

  1. public class MainActivity extends Activity {  
  2.  
  3.     /**  
  4.      * 側滑布局對象,用於通過手指滑動將左側的菜單布局進行顯示或隱藏。  
  5.      */ 
  6.     private SlidingLayout slidingLayout;  
  7.  
  8.     /**  
  9.      * menu按鈕,點擊按鈕展示左側布局,再點擊一次隱藏左側布局。  
  10.      */ 
  11.     private Button menuButton;  
  12.  
  13.     /**  
  14.      * 放在content布局中的ListView。  
  15.      */ 
  16.     private ListView contentListView;  
  17.  
  18.     /**  
  19.      * 作用於contentListView的適配器。  
  20.      */ 
  21.     private ArrayAdapter<String> contentListAdapter;  
  22.  
  23.     /**  
  24.      * 用於填充contentListAdapter的數據源。  
  25.      */ 
  26.     private String[] contentItems = { "Content Item 1", "Content Item 2", "Content Item 3",  
  27.             "Content Item 4", "Content Item 5", "Content Item 6", "Content Item 7",  
  28.             "Content Item 8", "Content Item 9", "Content Item 10", "Content Item 11",  
  29.             "Content Item 12", "Content Item 13", "Content Item 14", "Content Item 15",  
  30.             "Content Item 16" };  
  31.  
  32.     @Override 
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_main);  
  36.         slidingLayout = (SlidingLayout) findViewById(R.id.slidingLayout);  
  37.         menuButton = (Button) findViewById(R.id.menuButton);  
  38.         contentListView = (ListView) findViewById(R.id.contentList);  
  39.         contentListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,  
  40.                 contentItems);  
  41.         contentListView.setAdapter(contentListAdapter);  
  42.         // 將監聽滑動事件綁定在contentListView上  
  43.         slidingLayout.setScrollEvent(contentListView);  
  44.         menuButton.setOnClickListener(new OnClickListener() {  
  45.             @Override 
  46.             public void onClick(View v) {  
  47.                 // 實現點擊一下menu展示左側布局,再點擊一下隱藏左側布局的功能  
  48.                 if (slidingLayout.isLeftLayoutVisible()) {  
  49.                     slidingLayout.scrollToRightLayout();  
  50.                 } else {  
  51.                     slidingLayout.scrollToLeftLayout();  
  52.                 }  
  53.             }  
  54.         });  
  55.     }  
  56.  
  57. }  

上述代碼重點是調用SlidingLayout的setScrollEvent方法,為ListView注冊touch事件。同時給按鈕添加了一個點擊事件,實現了點擊一下顯示左邊布局,再點擊一下隱藏左邊布局的功能。

 

最後還是老規矩,給出AndroidManifest.xml的代碼:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     package="com.example.slide" 
  4.     android:versionCode="1" 
  5.     android:versionName="1.0" > 
  6.  
  7.     <uses-sdk 
  8.         android:minSdkVersion="8" 
  9.         android:targetSdkVersion="8" /> 
  10.  
  11.     <application 
  12.         android:allowBackup="true" 
  13.         android:icon="@drawable/ic_launcher" 
  14.         android:label="@string/app_name" 
  15.         android:theme="@android:style/Theme.NoTitleBar" > 
  16.         <activity 
  17.             android:name="com.example.slide.MainActivity" 
  18.             android:label="@string/app_name" > 
  19.             <intent-filter> 
  20.                 <action android:name="android.intent.action.MAIN" /> 
  21.  
  22.                 <category android:name="android.intent.category.LAUNCHER" /> 
  23.             </intent-filter> 
  24.         </activity> 
  25.     </application> 
  26.  
  27. </manifest> 

好了,現在讓我們運行一下吧。首先是程序打開的時候,顯示的是右邊布局。用手指在界面上向右滑動,可以看到左邊布局出現。

 

                
 

而當左邊布局完全顯示的時候,效果圖如下:

                           
 

除此之外,點擊Menu按鈕也可以控制左邊布局的顯示和隱藏,大家可以自己試一下。

使用自定義布局的話,就可以用簡單的方式在任意Activity中加入滑動菜單功能,即使你有再多的Activity也不用怕了,一分鐘引入滑動菜單妥妥的。

再總結一下吧,向Activity中加入滑動菜單功能只需要兩步:

1. 在Acitivty的layout中引入我們自定義的布局,並且給這個布局要加入兩個直接子元素。

2. 在Activity中通過setScrollEvent方法,給一個View注冊touch事件。

 

補充:

由於這段文章寫的比較早了,那時寫的滑動菜單還存在著不少問題,我之後又將上面的代碼做了不少改動,編寫了一個修正版的滑動菜單,這個版本主要修正了以下內容:

1.將滑動方式改成了覆蓋型。
 

2.ListView上下滾動時不會輕易滑出菜單。

3.正在滑動時屏蔽掉內容布局上的事件。

4.當菜單布局展示時,點擊一下右側的內容布局,可以將菜單隱藏。

5.修復剛打開程序時,菜單可能會短暫顯示一下,然後瞬間消失的bug。

源碼下載,請點擊這裡

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved