`
king_tt
  • 浏览: 2258458 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

 
阅读更多

观察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                     @Override
114                     public void onLongPress(MotionEvent e) {
115                     }
116 
117                     @Override
118                     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                     @Override
133                     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     @Override
144     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     @Override
161     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     @Override
170     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 whichScreen
216      */
217     public void scrollToScreen(int whichScreen) {
218             if (getFocusedChild() != null && whichScreen != currentScreenIndex
219                             && 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             else
231                 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         else
250             scrollToScreen(2);
251     }
252 
253     public interface OnScrollSideChangedListener
254     {
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         <Button
15             android:layout_width="200dp"
16             android:layout_height="wrap_content"
17             android:text="左菜单一" />
18         <Button
19             android:layout_width="200dp"
20             android:layout_height="wrap_content"
21             android:text="左菜单二" />
22     </LinearLayout>
23 
24     <LinearLayout
25         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         <LinearLayout
31             android:layout_width="wrap_content"
32             android:layout_height="wrap_content"
33             android:layout_weight="1"
34             android:orientation="vertical" >
35         </LinearLayout>
36         <LinearLayout
37             android:layout_width="200dp"
38             android:layout_height="wrap_content"
39             android:orientation="vertical" >
40             <Button
41                 android:layout_width="match_parent"
42                 android:layout_height="wrap_content"
43                 android:text="右菜单一" />
44             <Button
45                 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.ScrollLayout
53         android:layout_width="match_parent"
54         android:orientation="vertical"
55         android:id="@+id/my_scrollLayout"
56         android:layout_height="match_parent">
57         <LinearLayout
58             android:layout_width="match_parent"
59             android:layout_height="match_parent"
60             android:background="#aaa"
61             android:orientation="vertical" >
62 
63 
64             <Button
65                 android:id="@+id/button1"
66                 android:layout_width="match_parent"
67                 android:layout_height="wrap_content"
68                 android:text="Button Button" />
69 
70             <Spinner
71                 android:id="@+id/spinner1"
72                 android:layout_width="match_parent"
73                 android:layout_height="wrap_content" />
74 
75             <SeekBar
76                 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             @Override
11             public void onScrollSideChanged(View v, boolean leftSide) {
12                 if(leftSide)
13                 {
14                     right.setVisibility(View.GONE);
15                     left.setVisibility(View.VISIBLE);
16                 }else
17                 {
18                     right.setVisibility(View.VISIBLE);
19                     left.setVisibility(View.GONE);
20                 }
21             }
22         });
复制代码

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

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

相关推荐

    Android实现导航菜单左右滑动效果

    为了实现左右滑动的效果,你需要在`Activity`或`Fragment`中初始化`ViewPager`并设置适配器。在`onCreate()`或`onActivityCreated()`方法中,找到`ViewPager`实例,然后调用`setAdapter()`方法传入之前创建的`...

    Android实现图片左右滑动效果

    在Android开发中,实现图片左右滑动效果是常见的需求,比如在查看相册或轮播图时。这个功能可以通过多种方式实现,其中最常用的是使用ViewPager组件。ViewPager允许用户通过左右滑动手势在多个页面之间切换,非常...

    android网易新闻左右滑动菜单

    总的来说,实现"网易新闻左右滑动菜单"需要深入理解Android的视图系统、触摸事件处理以及动画机制。开发者需要具备扎实的布局设计和组件使用能力,同时对用户体验有深刻的理解,才能打造出既美观又实用的滑动菜单。...

    android 模仿酷狗 左右滑动 菜单

    首先,要实现左右滑动菜单,我们需要创建一个可以容纳多个页面的容器,如ViewPager。ViewPager允许用户通过水平滑动手势在不同的页面之间切换,是实现此类效果的基础。在Android SDK中,ViewPager已经提供了这样的...

    android slide menu(左右滑动菜单)

    1. **DrawerLayout**:这是Android SDK中内置的一个布局组件,专门用于实现滑动菜单。DrawerLayout允许你在主内容视图旁边添加一个可滑动的“抽屉”布局,这个抽屉通常包含菜单项。开发者可以设置手势监听器,监听...

    【Android】自定义左右滑动菜单

    本项目“【Android】自定义左右滑动菜单”就是这样一个实例,它旨在实现一个可滑动的侧边菜单,用户可以通过左右滑动来显示或隐藏菜单,提升应用的用户体验。 首先,我们来看菜单布局。在Android中,布局是UI设计的...

    android导航菜单横向左右滑动

    在“android导航菜单横向左右滑动”的场景下,我们关注的是如何实现一个可左右滑动的水平滚动视图,即HorizontalScrollView,并与下方的控件进行联动交互。以下将详细介绍这一主题。 首先,HorizontalScrollView是...

    android 仿PPath 侧边左右 滑动菜单

    android 仿PPath 侧边左右 滑动菜单 对于View 的管理 我只是单纯模仿IOS UINavigationController API来做的 卡壳了 对 View 的管理很郁闷 。 界面切换 界面退出 有动画 和没动画 。 希望大家看看 指点指点

    Android 仿美团网实现左右滑动查看更多分类的功能

    在Android应用开发中,我们经常会遇到需要实现类似美团网那样,可以左右滑动查看不同分类的功能。这个功能的核心在于提供一个流畅的用户界面,让用户能够方便地浏览和切换多个类别。在这里,我们将深入探讨如何使用...

    Android顶部、底部菜单左右滑动

    在实现左右滑动的过程中,开发者可能用到`SwipeRefreshLayout`,这是一个允许用户通过下拉刷新内容的组件。然而,对于左右滑动的需求,`ViewPager`是一个更合适的工具。`ViewPager`允许用户左右滑动页面,通常与`...

    Android项目导航菜单横向左右滑动并和下方的控件实现联动.rar

    本项目"Android项目导航菜单横向左右滑动并和下方的控件实现联动"就是针对这一需求设计的,它实现了侧滑导航菜单与主内容区域的动态联动效果。这种效果常见于许多流行的移动应用中,比如Google Maps和Facebook等。 ...

    Android实现顶部导航菜单左右滑动效果

    本文给大家介绍在Android中如何实现顶部导航菜单左右滑动效果,具体内容如下 第一种解决方案: 实现原理是使用android-support-v4.jar包中ViewPager控件,在ViewPager控件中设置流布局,再在流布局中设置几项...

    android 左右滑动菜单

    在Android开发中,实现左右滑动菜单是一种常见的交互设计,它可以提供类似iOS设备上"智慧无锡"的功能。这种设计能够使用户通过简单的手势操作在主界面与侧边菜单之间切换,提升应用程序的用户体验。以下是对如何在...

    Android 左右滑动菜单 DrawerLayout简单实现

    非常简单地实现左右滑动菜单。 导航抽屉可以显示在屏幕的左右两侧,默认情况下是隐藏的,当用户用手指从边缘向另一侧滑动的时候,会在内容上方出现一个隐藏的面板,此时内容视图区域会变暗。当点击面板外部或者向...

    Android上的菜单左右滑动菜单,android-menudrawer

    Android上的菜单展示风格各异,其中用得最多且体验最好的莫过于左右滑动来显示隐藏的菜单,android-menudrawer是一个滑动 式菜单实现,允许用户在应用当中实现无缝导航。该项目具有多种菜单展示效果,其中最常见的...

    Android ViewPager实现左右循环滑动及轮播效果

    在标题“Android ViewPager实现左右循环滑动及轮播效果”中,提到的关键技术点是使ViewPager具备循环滑动和轮播功能。下面我们将深入探讨如何实现这些效果。 1. **ViewPager基础**: ViewPager最初是Android ...

    Android 高仿QQ HD mini左右滑动菜单栏效果

    1. 自定义ViewGroup:在Android中,我们可以创建一个自定义的布局容器,继承自LinearLayout、RelativeLayout等基础布局,然后重写onTouchEvent()方法,处理触摸事件,实现左右滑动的效果。在这个过程中,你需要监听...

    Android左右菜单滑动

    1. **手势检测**:为了实现左右滑动的效果,项目中使用了手势检测技术。在Android中,这通常通过` GestureDetector `类来实现。`GestureDetector`可以监听滑动、点击等基本手势,通过重写其回调方法,如`onDown()`, ...

    android实现仿qq中listview滑动菜单

    接下来,我们将深入探讨如何在Android中实现这样的滑动菜单。 首先,我们需要了解ListView的基本概念。ListView是Android中的一个视图组件,用于显示大量数据的列表。它可以动态加载数据,并且支持滚动操作。为了...

Global site tag (gtag.js) - Google Analytics