滑动菜单特效实现
2016-01-18 15:27
381 查看
这次是滑动特效实现,代码是看的郭霖老师的,但是看了代码有点懵懵懂懂的,所以自己就对代码进行更详细的解读。
步骤:
1.首先我们要初始化几个参数:
menuPadding=100; //完全显示Menu时,留给Content的宽度
screenWidth; //初始化为屏幕宽度
leftEdge; //也就是menu滑到最左边,menu布局leftMargin的最小值,也就是后面滑动只要小于了它,就不能再向左滑动了。
rightEdge; //menu滑到最右边,leftMargin不能再增加了。
2. 重写 onTouch事件,分为:手指按下,手指移动,手指抬起。
按下时:获取按下的x值;移动时:判断滑动的位置,根据 leftEdge最左边 ,rightEdge最右边;
抬起时:判断是否需要显示 Menu或者 Content 。
3. 根据AsyncTask来显示手指在屏幕上滑动的样子。(最后我也不清楚为什么用到AsyncTask)
这是我 activity_main 代码:
我的 MainActivity.java :
步骤:
1.首先我们要初始化几个参数:
menuPadding=100; //完全显示Menu时,留给Content的宽度
screenWidth; //初始化为屏幕宽度
leftEdge; //也就是menu滑到最左边,menu布局leftMargin的最小值,也就是后面滑动只要小于了它,就不能再向左滑动了。
rightEdge; //menu滑到最右边,leftMargin不能再增加了。
2. 重写 onTouch事件,分为:手指按下,手指移动,手指抬起。
按下时:获取按下的x值;移动时:判断滑动的位置,根据 leftEdge最左边 ,rightEdge最右边;
抬起时:判断是否需要显示 Menu或者 Content 。
3. 根据AsyncTask来显示手指在屏幕上滑动的样子。(最后我也不清楚为什么用到AsyncTask)
这是我 activity_main 代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <LinearLayout android:id="@+id/menu" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="@color/yellow" > </LinearLayout> <LinearLayout android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="@color/blue"> </LinearLayout> </LinearLayout>
我的 MainActivity.java :
package com.slidemenudemo; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; public class MainActivity extends Activity implements OnTouchListener { /** * 自定义的速度,当用户达到这个速度时, * 就可以是menu到content的转换,或者content到menu的转换 */ private static final int SPEED=200; /** * 手指按下时X的坐标 */ private float xDown; /** * 手指抬起时X的坐标 */ private float xUp; /** * 手指滑动时X的坐标 */ private float xMove; private View menu; private View content; /** * menu菜单的参数,根据它来改变leftMargin */ private LinearLayout.LayoutParams menuParams; private boolean isMenuVisible; private int screenWidth; /** * menu滑动到最左端时的最小值 */ private int leftEdge; /** * menu滑动到最右端时的最大值 */ private int rightEdge; /** * menu显示时,留给content的宽度 */ private int menuPadding; /** * 用于计算手指滑动的速度。 */ private VelocityTracker mVelocityTracker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); content.setOnTouchListener(this); } /** * 初始化 */ private void initView(){ WindowManager window=(WindowManager) getSystemService(Context.WINDOW_SERVICE); screenWidth=window.getDefaultDisplay().getWidth(); menu=findViewById(R.id.menu); content=findViewById(R.id.content); menuParams=(LinearLayout.LayoutParams)menu.getLayoutParams(); menuPadding=100; menuParams.width=screenWidth-menuPadding; leftEdge=-menuParams.width; rightEdge=0; menuParams.leftMargin=leftEdge; content.getLayoutParams().width=screenWidth; } @Override public boolean onTouch(View v, MotionEvent event) { createVelocityTracker(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: xDown=event.getRawX(); break; case MotionEvent.ACTION_MOVE: // 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整menu的leftMargin值,从而显示和隐藏menu xMove=event.getRawX(); int distanceX=(int) (xMove-xDown); if(isMenuVisible){ menuParams.leftMargin=distanceX; }else { menuParams.leftMargin=distanceX+leftEdge; }if(menuParams.leftMargin<leftEdge){ menuParams.leftMargin=leftEdge; }else if(menuParams.leftMargin>rightEdge){ menuParams.leftMargin=rightEdge; } menu.setLayoutParams(menuParams); break; case MotionEvent.ACTION_UP: // 手指抬起时,进行判断当前手势的意图,从而决定是滚动到menu界面,还是滚动到content界面 xUp=event.getRawX(); if(wantToShowMenu()){ if(shouldShowMenu()){ ScollToMenu(); }else { ScollToContent(); } } else if(wantToShowContent()){ if(shouldShowContent()){ ScollToContent(); }else { ScollToMenu(); } } break; } recycleVelocityTracker(); return true; } private boolean wantToShowMenu(){ return xUp-xDown > 0 && !isMenuVisible; } private boolean wantToShowContent(){ return xUp-xDown < 0 && isMenuVisible; } private boolean shouldShowMenu(){ return xUp-xDown > screenWidth/2 || getScrollVelocity() > SPEED; } private boolean shouldShowContent(){ return xDown-xUp + menuPadding >screenWidth/2 || getScrollVelocity() > SPEED ; } private void ScollToMenu(){ new ScrollTask().execute(30); } private void ScollToContent(){ new ScrollTask().execute(-30); } /** * 创建VelocityTracker对象,并将触摸content界面的滑动事件加入到VelocityTracker当中。 * * @param event * content界面的滑动事件 */ private void createVelocityTracker(MotionEvent event){ if(mVelocityTracker==null){ mVelocityTracker=VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); } private void recycleVelocityTracker(){ mVelocityTracker.recycle(); mVelocityTracker=null; } /** * 获取手指在content界面滑动的速度。 * * @return 滑动速度,以每秒钟移动了多少像素值为单位。 */ private int getScrollVelocity(){ mVelocityTracker.computeCurrentVelocity(1000); int velocity=(int) mVelocityTracker.getXVelocity(); return Math.abs(velocity); } class ScrollTask extends AsyncTask<Integer, Integer, Integer>{ @Override protected Integer doInBackground(Integer... speed) { int leftMargin=menuParams.leftMargin; // 根据传入的速度来滚动界面,当滚动到达左边界或右边界时,跳出循环。 while(true){ leftMargin=leftMargin+speed[0]; if(leftMargin>rightEdge){ leftMargin=rightEdge; break; } if(leftMargin<leftEdge){ leftMargin=leftEdge; break; } publishProgress(leftMargin); //为了产生滑动效果,而睡眠20毫秒 sleep(20); } if (speed[0] > 0) { isMenuVisible = true; } else { isMenuVisible = false; } return leftMargin; } @Override protected void onProgressUpdate(Integer... leftMargin) { menuParams.leftMargin=leftMargin[0]; menu.setLayoutParams(menuParams); } @Override protected void onPostExecute(Integer leftMargin) { menuParams.leftMargin=leftMargin; menu.setLayoutParams(menuParams); } } private void sleep(long mills){ try { Thread.sleep(mills); } catch (InterruptedException e) { e.printStackTrace(); } } }
相关文章推荐
- iOS-内测-蒲公英应用内测使用
- 2/8/16 转10进制
- 获取URL传进来的参数,法定节假日或者平时周末(排除补假)显示、隐藏电话号码
- C# 读取EXCEL数据
- 《ios与os x多线程和内存管理》
- 在网页上获取当前日期,数字时钟
- GTP(GPRS Tunnelling Protocol)协议http://blog.csdn.net/stephen_yin/article/details/6951237
- mysql判断表是否存在的语句
- Java异步回调
- 在Android6.0上给外置SD卡增加一个路径
- python 脚本风格
- Thinkphp简单无限级分类
- SQL
- Divide and conquer:Dropping tests(POJ 2976)
- 将博客搬至CSDN
- Tips For Autolayout
- linux 增加sudo权限
- 信必优用144部Windows Phone组超炫矩阵屏幕
- Android获取设备隐私 忽略6.0权限管理
- 希尔排序