android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现.

    实现方法:我们自定义一个ViewGroup实现左右滑动,第一屏隐藏,第二屏显示.

    代码如下:

  1. package com.jj.sliding_6;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.util.Log;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.view.ViewTreeObserver;  
  9. import android.view.View.MeasureSpec;  
  10. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
  11. import android.widget.AbsoluteLayout;  
  12. import android.widget.LinearLayout;  
  13. import android.widget.ListView;  
  14. import android.widget.RelativeLayout;  
  15. import android.widget.Scroller;  
  16.   
  17. /*** 
  18.  * 自定义view 
  19.  *  
  20.  * @author zhangjia 
  21.  *  
  22.  */  
  23. public class MyViewGroup extends ViewGroup {  
  24.     private Scroller scroller;// 滑动  
  25.     private int distance;// 滑动距离  
  26.   
  27.     private View menu_view, content_view;  
  28.     private int duration = 500;  
  29.   
  30.     private ViewTreeObserver viewTreeObserver;  
  31.     private Context context;  
  32.     private CloseAnimation closeAnimation;  
  33.   
  34.     public static boolean isMenuOpned = false;// 菜单是否打开  
  35.   
  36.     public MyViewGroup(Context context) {  
  37.         super(context, null);  
  38.     }  
  39.   
  40.     public void setCloseAnimation(CloseAnimation closeAnimation) {  
  41.         this.closeAnimation = closeAnimation;  
  42.     }  
  43.   
  44.     public MyViewGroup(Context context, AttributeSet attrs) {  
  45.         super(context, attrs);  
  46.         this.context = context;  
  47.         scroller = new Scroller(context);  
  48.     }  
  49.   
  50.     public void setDistance(int distance) {  
  51.         this.distance = distance;  
  52.     }  
  53.   
  54.     @Override  
  55.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  56.         if (changed) {  
  57.             menu_view = getChildAt(0);// 获取滑动菜单的view  
  58.             content_view = getChildAt(1);// 获得主页view  
  59.   
  60.             // 相当于fill_parent  
  61.             content_view.measure(00);  
  62.             content_view.layout(00, getWidth(), getHeight());  
  63.         }  
  64.     }  
  65.   
  66.     @Override  
  67.     public void computeScroll() {  
  68.         Log.e("jj""isMenuOpned=" + isMenuOpned);  
  69.         if (scroller.computeScrollOffset()) {  
  70.             scrollTo(scroller.getCurrX(), scroller.getCurrY());  
  71.             postInvalidate();// 刷新  
  72.             if (closeAnimation != null)  
  73.                 closeAnimation.closeMenuAnimation();  
  74.   
  75.         }else{  
  76.             MainActivity.isScrolling=false;  
  77.         }  
  78.     }  
  79.   
  80.     void showMenu() {  
  81.         Log.e("jj""shoeMenu");  
  82.         isMenuOpned = true;  
  83.         scroller.startScroll(getScrollX(), 0, -distance, 0, duration);  
  84.         invalidate();// 刷新  
  85.     }  
  86.   
  87.     // 关闭菜单(执行自定义动画)  
  88.     void closeMenu() {  
  89.         Log.e("jj""closeMenu");  
  90.         isMenuOpned = false;  
  91.         scroller.startScroll(getScrollX(), 0, distance, 0, duration);  
  92.   
  93.         invalidate();// 刷新  
  94.     }  
  95.   
  96.     // 关闭菜单(执行自定义动画)  
  97.     void closeMenu_1() {  
  98.         isMenuOpned = false;  
  99.         scroller.startScroll(getScrollX(), 0, distance - getWidth(), 0,  
  100.                 duration);  
  101.         invalidate();// 刷新  
  102.     }  
  103.   
  104.     // 关闭菜单(执行自定义动画)  
  105.     void closeMenu_2() {  
  106.         isMenuOpned = false;  
  107.         scroller.startScroll(getScrollX(), 0, getWidth(), 0, duration);  
  108.         invalidate();// 刷新  
  109.     }  
  110.   
  111.     /*** 
  112.      * Menu startScroll(startX, startY, dx, dy) 
  113.      *  
  114.      * dx=e1的减去e2的x,所以右移为负,左移动为正 dx为移动的距离,如果为正,则标识向左移动|dx|,如果为负,则标识向右移动|dx| 
  115.      */  
  116.     void slidingMenu() {  
  117.         Log.e("jj""slidingMenu");  
  118.         // 没有超过半屏  
  119.         if (getScrollX() > -getWidth() / 2) {  
  120.             scroller.startScroll(getScrollX(), 0, -getScrollX(), 0, duration);  
  121.             isMenuOpned = false;  
  122.         }  
  123.         // 超过半屏  
  124.         else if (getScrollX() <= -getWidth() / 2) {  
  125.             scroller.startScroll(getScrollX(), 0, -(distance + getScrollX()),  
  126.                     0, duration);  
  127.             isMenuOpned = true;  
  128.         }  
  129.   
  130.         invalidate();// 刷新  
  131.         Log.v("jj""getScrollX()=" + getScrollX());  
  132.     }  
  133. }  
  134.   
  135.   abstract class CloseAnimation {  
  136.     // 点击list item 关闭menu动画  
  137.     public void closeMenuAnimation() {  
  138.   
  139.     };  
  140. }  

上诉大部分我都加以注释,想必不用我解释太多,大家仔细看都应该可以看懂.

之后我们只需要在MainActivity中把要显示的view添加进去就可以了。

运行效果:

        

 我把源码上传网上,大家可以下载运行,如有不足请留言.

说明一点:listview上下左右滑动冲突没有解决,不过我运行看过很多应用,要么listview不能左右滑动,要么能左右滑动但是listview不到一屏.


源码下载


下面我介绍另外一种方法,这种方法比较简单,但是有点不实用.不过对SlidingMenu滑动菜单要求不高的应用完全可以了,如:云中书城等,没有用到手势时时滑动.

实现方法:我们在点击或者滑动的时候获取当前view的切图bitmap,然后将这个bitmap传递到打开后的activity,在这个activity中布局具体如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/layout"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent" >  
  6.   
  7.     <FrameLayout  
  8.         android:id="@+id/slideout_placeholder"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent"  
  11.         android:background="#777777" >  
  12.   
  13.         <ListView  
  14.             android:id="@+id/list"  
  15.             android:layout_width="fill_parent"  
  16.             android:layout_height="fill_parent"  
  17.             android:cacheColorHint="#00000000" />  
  18.     </FrameLayout>  
  19.   
  20.     <ImageView  
  21.         android:id="@+id/slidedout_cover"  
  22.         android:layout_width="fill_parent"  
  23.         android:layout_height="fill_parent"  
  24.         android:scaleType="fitXY" />  
  25.   
  26. </AbsoluteLayout>  

这种布局目的就是让用户觉得我们操作的是一个view.

具体实现:我将代码上传网上,大家自行下载运行,有不足之处,自行调整.

效果图;

posted @ 2013-12-18 17:41  brave-sailor  阅读(317)  评论(0编辑  收藏  举报