观察qqminihd界面,发现其界面能够左右滑动来实现两侧菜单效果。

自定义Layout:ScrollLayout.java

直接贴出代码:

View Code 复制代码
  1 package grimbo.android.demo.slidingmenu;  2   3 import android.content.Context;  4 import android.util.AttributeSet;  5 import android.util.Log;  6 import android.view.GestureDetector;  7 import android.view.GestureDetector.OnGestureListener;  8 import android.view.MotionEvent;  9 import android.view.View; 10 import android.view.ViewConfiguration; 11 import android.view.animation.AnimationUtils; 12 import android.widget.LinearLayout; 13 import android.widget.Scroller; 14  15 public class ScrollLayout extends LinearLayout { 16  17 //    private static final String TAG = "scroller"; 18  19     private Scroller scroller; 20  21     private int currentScreenIndex; 22  23     private GestureDetector gestureDetector; 24  25     // 设置一个标志位,防止底层的onTouch事件重复处理UP事件 26     private boolean fling; 27  28     /** 29      * 菜单栏的宽度 30      */ 31     int menuWidth=80; 32      33     /** 34      * 显示左边菜单 35      * 否则显示右边菜单 36      */ 37     private boolean showLeft=true; 38      39     /** 40      * 滚出边界监听器 41      */ 42     private OnScrollSideChangedListener scrollSideChangedListener; 43      44     public Scroller getScroller() { 45             return scroller; 46     } 47  48     public OnScrollSideChangedListener getScrollSideChangedListener() { 49         return scrollSideChangedListener; 50     } 51  52     public void setScrollSideChangedListener( 53             OnScrollSideChangedListener scrollSideChangedListener) { 54         this.scrollSideChangedListener = scrollSideChangedListener; 55     } 56  57     public ScrollLayout(Context context, AttributeSet attrs) { 58             super(context, attrs); 59             initView(context); 60     } 61  62     public ScrollLayout(Context context) { 63             super(context); 64             initView(context); 65     } 66  67     private void initView(final Context context) { 68             this.scroller = new Scroller(context,AnimationUtils.loadInterpolator(context, 69                     android.R.anim.overshoot_interpolator)); 70  71             this.gestureDetector = new GestureDetector(new OnGestureListener() { 72  73                     @Override 74                     public boolean onSingleTapUp(MotionEvent e) { 75                             return false; 76                     } 77  78                     @Override 79                     public void onShowPress(MotionEvent e) { 80                     } 81  82                     @Override 83                     public boolean onScroll(MotionEvent e1, MotionEvent e2, 84                                     float distanceX, float distanceY) { 85  86                             {// 防止向第一页之前移动 87                                 if(1==currentScreenIndex) 88                                 { 89                                     int screenLeft=getWidth()-menuWidth; 90                                     if(showLeft && getScrollX()>screenLeft) 91                                     { 92                                         showLeft=false; 93 //                                        Log.e("TAG","显示右边菜单栏"); 94                                         if(null!=scrollSideChangedListener) 95                                             scrollSideChangedListener.onScrollSideChanged(ScrollLayout.this, showLeft); 96                                     } 97                                     else if(!showLeft && getScrollX()<screenLeft) 98                                     { 99                                         showLeft=true;100 //                                        Log.e("TAG","显示左边菜单栏");101                                         if(null!=scrollSideChangedListener)102                                             scrollSideChangedListener.onScrollSideChanged(ScrollLayout.this, showLeft);103                                     }104                                 }105                                 106                                     fling = true;107                                     scrollBy((int) distanceX, 0);108 //                                    Log.d("TAG", "on scroll>>>>>>>>>>>>>>>>>移动<<<<<<<<<<<<<<>>>");109                             }110                             return true;111                     }112 113                     @Override114                     public void onLongPress(MotionEvent e) {115                     }116 117                     @Override118                     public boolean onFling(MotionEvent e1, MotionEvent e2,119                                     float velocityX, float velocityY) {120                         121                             if (Math.abs(velocityX) > ViewConfiguration.get(context)122                                             .getScaledMinimumFlingVelocity()) 123                             {// 判断是否达到最小轻松速度,取绝对值的124                                 fling = true;125                                 snapToDestination();126 //                                Log.d(TAG, "on scroll>>>>>>>>>>>>>>>>>滑动<<<<<<<<<<<<<<>>>");127                             }128 129                             return true;130                     }131 132                     @Override133                     public boolean onDown(MotionEvent e) {134                             return false;135                     }136             });137             138     }139     //每一个屏的边界值140     //0----[getWidth()-20]----[2*getWidth()-20]-----[3*getWidth()-40]141     142     143     @Override144     protected void onLayout(boolean changed, int left, int top, int right,145                     int bottom) {146             /**147              * 设置布局,将子视图顺序横屏排列148              */149             super.onLayout(changed, left, top, right, bottom);150             int move=getWidth()-menuWidth;151             for (int i = 0; i < getChildCount(); i++) 152             {153                     View child = getChildAt(i);154 //                    child.setVisibility(View.VISIBLE);155                     //移动一定的距离156                     child.layout(child.getLeft()+move,child.getTop(),child.getRight()+move,child.getBottom());157             }158     }159 160     @Override161     public void computeScroll() {162             if (scroller.computeScrollOffset()) {163 //                    Log.d(TAG, ">>>>>>>>>>computeScroll>>>>>"+scroller.getCurrX());164                     scrollTo(scroller.getCurrX(), 0);165                     postInvalidate();166             }167     }168 169     @Override170     public boolean onTouchEvent(MotionEvent event) {171             172             float x2s=getScrollX()+event.getX();173             174             if(x2s<getWidth()-menuWidth || x2s>2*getWidth()-menuWidth)175             {//动作在区域外面176                 if(!fling)//没有在滑动177                 {178 //                    Log.d(TAG, "on scroll>>>>>>>>>>>>>>>>>动作在区域外面 没有在滑动<<<<<<<<<<<<<<>>>");179                     return false;180                 }181                 else if(MotionEvent.ACTION_UP!=event.getAction())182                 {//否则如果也不是抬起手势,则强制模拟抬起183                     snapToDestination();184                     fling = false;185 //                    Log.d(TAG, "on scroll>>>>>>>>>>>>>>>>>动作在区域外面 在滑动 也不是抬起手势<<<<<<<<<<<<<<>>>");186                     return false;187                 }188 //                Log.e(TAG, "on scroll>>>>>>>>>>>>>>>>>动作在区域外面 在滑动 是抬起手势<<<<<<<<<<<<<<>>>");189             }190             191             gestureDetector.onTouchEvent(event);192 193             switch (event.getAction()) {194             case MotionEvent.ACTION_DOWN:195                     break;196             case MotionEvent.ACTION_MOVE:197                     break;198             case MotionEvent.ACTION_UP:199 //                    Log.d(TAG, ">>ACTION_UP:>>>>>>>> MotionEvent.ACTION_UP>>>>>");200 //                    if (!fling) 201                     {202                             snapToDestination();203                     }204                     fling = false;205                     break;206             default:207                     break;208             }209             return true;210     }211 212     /**213      * 切换到指定屏214      * 215      * @param whichScreen216      */217     public void scrollToScreen(int whichScreen) {218             if (getFocusedChild() != null && whichScreen != currentScreenIndex219                             && getFocusedChild() == getChildAt(currentScreenIndex)) {220                     getFocusedChild().clearFocus();221             }222             int delta = 0;223             224             if(whichScreen==0)225                 delta= - getScrollX();226             else if(whichScreen==1)227                 delta= getWidth()-menuWidth- getScrollX();228             else if(whichScreen==2)229                 delta= 2*(getWidth()-menuWidth)- getScrollX();230             else231                 return;232 //                delta = whichScreen * getWidth() - getScrollX();233             234             scroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);235             invalidate();236 237             currentScreenIndex = whichScreen;238     }239 240     /**241      * 根据当前x坐标位置确定切换到第几屏242      */243     private void snapToDestination() {244         245         if(getScrollX()<(getWidth()-menuWidth)/2)246             scrollToScreen(0);247         else if(getScrollX()<(getWidth()-menuWidth+getWidth()/2))248             scrollToScreen(1);249         else250             scrollToScreen(2);251     }252 253     public interface OnScrollSideChangedListener254     {255         public void onScrollSideChanged(View v,boolean leftSide);256     }257 }
复制代码

接下来,在定义activity里面的布局my_layout.xml:

View Code 复制代码
 1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     xmlns:app="http://schemas.android.com/apk/res/grimbo.android.demo.slidingmenu" 4     android:id="@+id/FrameLayout1" 5     android:layout_width="match_parent" 6     android:layout_height="match_parent" > 7     <LinearLayout 8         android:layout_width="match_parent" 9         android:layout_height="match_parent"10         android:id="@+id/left_menu"11         android:background="#333"12         android:orientation="vertical" >13 14         <Button15             android:layout_width="200dp"16             android:layout_height="wrap_content"17             android:text="左菜单一" />18         <Button19             android:layout_width="200dp"20             android:layout_height="wrap_content"21             android:text="左菜单二" />22     </LinearLayout>23 24     <LinearLayout25         android:id="@+id/right_menu"26         android:layout_width="match_parent"27         android:layout_height="match_parent"28         android:background="#666"29         android:orientation="horizontal" >30         <LinearLayout31             android:layout_width="wrap_content"32             android:layout_height="wrap_content"33             android:layout_weight="1"34             android:orientation="vertical" >35         </LinearLayout>36         <LinearLayout37             android:layout_width="200dp"38             android:layout_height="wrap_content"39             android:orientation="vertical" >40             <Button41                 android:layout_width="match_parent"42                 android:layout_height="wrap_content"43                 android:text="右菜单一" />44             <Button45                 android:layout_width="match_parent"46                 android:layout_height="wrap_content"47                 android:text="右菜单二" />48             49         </LinearLayout>50         51     </LinearLayout>52     <grimbo.android.demo.slidingmenu.ScrollLayout53         android:layout_width="match_parent"54         android:orientation="vertical"55         android:id="@+id/my_scrollLayout"56         android:layout_height="match_parent">57         <LinearLayout58             android:layout_width="match_parent"59             android:layout_height="match_parent"60             android:background="#aaa"61             android:orientation="vertical" >62 63 64             <Button65                 android:id="@+id/button1"66                 android:layout_width="match_parent"67                 android:layout_height="wrap_content"68                 android:text="Button Button" />69 70             <Spinner71                 android:id="@+id/spinner1"72                 android:layout_width="match_parent"73                 android:layout_height="wrap_content" />74 75             <SeekBar76                 android:id="@+id/seekBar1"77                 android:layout_width="match_parent"78                 android:layout_height="wrap_content" />79             80         </LinearLayout>81 82     </grimbo.android.demo.slidingmenu.ScrollLayout>83     84 </FrameLayout>
复制代码

最后,在activity里面的onCreate函数里加上:

View Code 复制代码
 1 setContentView(R.layout.my_layout); 2          3         final LinearLayout left=(LinearLayout)findViewById(R.id.left_menu); 4         final LinearLayout right=(LinearLayout)findViewById(R.id.right_menu); 5         right.setVisibility(View.GONE); 6         left.setVisibility(View.VISIBLE); 7          8         ScrollLayout mScrollLayout=(ScrollLayout)findViewById(R.id.my_scrollLayout); 9         mScrollLayout.setScrollSideChangedListener(new OnScrollSideChangedListener() {10             @Override11             public void onScrollSideChanged(View v, boolean leftSide) {12                 if(leftSide)13                 {14                     right.setVisibility(View.GONE);15                     left.setVisibility(View.VISIBLE);16                 }else17                 {18                     right.setVisibility(View.VISIBLE);19                     left.setVisibility(View.GONE);20                 }21             }22         });
复制代码

大功告成!左右滑动是弹性效果也一并实现~

android 自己实现qqminihd 左右滑动菜单效果

android 自己实现qqminihd 左右滑动菜单效果

android 自己实现qqminihd 左右滑动菜单效果

原创文章欢迎转载,转载请注明出处:http://www.cnblogs.com/zhouchanwen

更多相关文章

  1. 史上最全!最经典!最无私的Android资料(书籍+代码)分享-不要积分(求置
  2. Android 5中不同效果的Toast
  3. Android实现textview文字滚动显示(跑马灯效果)
  4. GreenDao自动生成Android数据库操作代码
  5. Android源代码下载与编译
  6. android实现节点进度条效果
  7. android启动时应用程序渐变效果
  8. 【Android】自定义环形菜单View
  9. Android应用libGDX引擎系列(一)-Android FrameWork 基于libGDX实

随机推荐

  1. Android(安卓)okHttp上传单张或多张照片
  2. Android全屏设置及取消全屏设置
  3. android如何往SDCard中存取图片
  4. android volley封装及源码解析
  5. Android引路蜂地图开发示例:放大、缩小
  6. NDK C++线程中如何调用JAVA API
  7. android 使用post方式上传文件
  8. android 中 LocalSocket的基本使用方法
  9. Android(安卓)导航类型
  10. Android经常使用开源组件汇总