- 浏览: 2258458 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
wahahachuang5:
web实时推送技术使用越来越广泛,但是自己开发又太麻烦了,我觉 ...
细说websocket - php篇 -
wahahachuang8:
挺好的,学习了
细说websocket - php篇 -
jacking124:
学习了!支持你,继续
初窥Linux 之 我最常用的20条命令 -
aliahhqcheng:
应该是可以实现的,没有看过源码。你可以参考下:http://w ...
Jackson 框架,轻易转换JSON
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
相关推荐
为了实现左右滑动的效果,你需要在`Activity`或`Fragment`中初始化`ViewPager`并设置适配器。在`onCreate()`或`onActivityCreated()`方法中,找到`ViewPager`实例,然后调用`setAdapter()`方法传入之前创建的`...
在Android开发中,实现图片左右滑动效果是常见的需求,比如在查看相册或轮播图时。这个功能可以通过多种方式实现,其中最常用的是使用ViewPager组件。ViewPager允许用户通过左右滑动手势在多个页面之间切换,非常...
总的来说,实现"网易新闻左右滑动菜单"需要深入理解Android的视图系统、触摸事件处理以及动画机制。开发者需要具备扎实的布局设计和组件使用能力,同时对用户体验有深刻的理解,才能打造出既美观又实用的滑动菜单。...
首先,要实现左右滑动菜单,我们需要创建一个可以容纳多个页面的容器,如ViewPager。ViewPager允许用户通过水平滑动手势在不同的页面之间切换,是实现此类效果的基础。在Android SDK中,ViewPager已经提供了这样的...
1. **DrawerLayout**:这是Android SDK中内置的一个布局组件,专门用于实现滑动菜单。DrawerLayout允许你在主内容视图旁边添加一个可滑动的“抽屉”布局,这个抽屉通常包含菜单项。开发者可以设置手势监听器,监听...
本项目“【Android】自定义左右滑动菜单”就是这样一个实例,它旨在实现一个可滑动的侧边菜单,用户可以通过左右滑动来显示或隐藏菜单,提升应用的用户体验。 首先,我们来看菜单布局。在Android中,布局是UI设计的...
在“android导航菜单横向左右滑动”的场景下,我们关注的是如何实现一个可左右滑动的水平滚动视图,即HorizontalScrollView,并与下方的控件进行联动交互。以下将详细介绍这一主题。 首先,HorizontalScrollView是...
android 仿PPath 侧边左右 滑动菜单 对于View 的管理 我只是单纯模仿IOS UINavigationController API来做的 卡壳了 对 View 的管理很郁闷 。 界面切换 界面退出 有动画 和没动画 。 希望大家看看 指点指点
在Android应用开发中,我们经常会遇到需要实现类似美团网那样,可以左右滑动查看不同分类的功能。这个功能的核心在于提供一个流畅的用户界面,让用户能够方便地浏览和切换多个类别。在这里,我们将深入探讨如何使用...
在实现左右滑动的过程中,开发者可能用到`SwipeRefreshLayout`,这是一个允许用户通过下拉刷新内容的组件。然而,对于左右滑动的需求,`ViewPager`是一个更合适的工具。`ViewPager`允许用户左右滑动页面,通常与`...
本项目"Android项目导航菜单横向左右滑动并和下方的控件实现联动"就是针对这一需求设计的,它实现了侧滑导航菜单与主内容区域的动态联动效果。这种效果常见于许多流行的移动应用中,比如Google Maps和Facebook等。 ...
本文给大家介绍在Android中如何实现顶部导航菜单左右滑动效果,具体内容如下 第一种解决方案: 实现原理是使用android-support-v4.jar包中ViewPager控件,在ViewPager控件中设置流布局,再在流布局中设置几项...
在Android开发中,实现左右滑动菜单是一种常见的交互设计,它可以提供类似iOS设备上"智慧无锡"的功能。这种设计能够使用户通过简单的手势操作在主界面与侧边菜单之间切换,提升应用程序的用户体验。以下是对如何在...
非常简单地实现左右滑动菜单。 导航抽屉可以显示在屏幕的左右两侧,默认情况下是隐藏的,当用户用手指从边缘向另一侧滑动的时候,会在内容上方出现一个隐藏的面板,此时内容视图区域会变暗。当点击面板外部或者向...
Android上的菜单展示风格各异,其中用得最多且体验最好的莫过于左右滑动来显示隐藏的菜单,android-menudrawer是一个滑动 式菜单实现,允许用户在应用当中实现无缝导航。该项目具有多种菜单展示效果,其中最常见的...
在标题“Android ViewPager实现左右循环滑动及轮播效果”中,提到的关键技术点是使ViewPager具备循环滑动和轮播功能。下面我们将深入探讨如何实现这些效果。 1. **ViewPager基础**: ViewPager最初是Android ...
1. 自定义ViewGroup:在Android中,我们可以创建一个自定义的布局容器,继承自LinearLayout、RelativeLayout等基础布局,然后重写onTouchEvent()方法,处理触摸事件,实现左右滑动的效果。在这个过程中,你需要监听...
1. **手势检测**:为了实现左右滑动的效果,项目中使用了手势检测技术。在Android中,这通常通过` GestureDetector `类来实现。`GestureDetector`可以监听滑动、点击等基本手势,通过重写其回调方法,如`onDown()`, ...
接下来,我们将深入探讨如何在Android中实现这样的滑动菜单。 首先,我们需要了解ListView的基本概念。ListView是Android中的一个视图组件,用于显示大量数据的列表。它可以动态加载数据,并且支持滚动操作。为了...