zoukankan      html  css  js  c++  java
  • android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]

    http://blog.csdn.net/jj120522/article/details/8095852

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

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

        代码如下:

    [java] view plaincopy
     
    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中布局具体如下:

    [java] view plaincopy
     
    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.

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

    效果图;



    源码下载

    这篇讲解比较少,不过大部分都加以注释,相信大家都看得明白.

    我看了有的朋友是对HorizontalScrollView进行的自定义,实现方法比较多,因人而异,总之只要实现效果就行.

     

    写到这里,不足的地方请之处,thanks for you .

     

     

     

         

  • 相关阅读:
    sql语言复习:学院-学生-教师-课程-学习-授课表上的一些操作
    JZOJ6358. 【NOIP2019模拟2019.9.15】小ω的仙人掌
    JZOJ6353. 【NOIP2019模拟】给(ca)
    【CSP-S2019模拟】09.13比赛总结
    【CSP-S2019模拟】09.11比赛总结
    JZOJ6341. 【NOIP2019模拟2019.9.4】C
    JZOJ6344. 【NOIP2019模拟2019.9.7】Huge Counting
    JZOJ6343. 【NOIP2019模拟2019.9.7】Medium Counting
    【随机编号】【 2019 Multi-University Training Contest 8】1008.Andy and Maze
    【吉如一线段树】JZOJ6270. 【省赛模拟8.10】序列
  • 原文地址:https://www.cnblogs.com/fx2008/p/3262620.html
Copyright © 2011-2022 走看看