5.触摸事件、侧滑菜单

触摸事件

侧滑菜单---

github-SlidingMenu

1.在ViewGroup中,让自己内容移动有以下三个方法个方法:

  • layout(l,t,r,b);
  • offsetTopAndBottom(offset)和offsetLeftAndRight(offset);
  • scrollTo和scrollBy方法;

注意:滚动的并不是viewgroup内容本身,而是它的矩形边框

它是瞬间移动的

2.在自定义ViewGroup中一般不需要去实现onMeasure,

我们去实现系统已有的ViewGroup,比如FrameLayout,

它会帮我们区实现onMeasure方法

3.让view在一段时间内移动到某个位置

a.使用自定义动画(让view在一段时间内做某件事)

b.使用Scroller(模拟一个执行流程,)

layout会影响measure过的宽高

scrollTo理解

布局:

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity" >
  6. <com.ly.slidemenu.view.SlideMenu
  7. android:id="@+id/slideMenu"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent" >
  10. <!-- 菜单界面的布局 -->
  11. <include layout="@layout/layout_menu"/>
  12. <!-- 主界面的布局 -->
  13. <include layout="@layout/layout_main"/>
  14. </com.ly.slidemenu.view.SlideMenu>
  15. </RelativeLayout>

SlideMenu

  1. public class SlideMenu extends FrameLayout{
  2. private View menuView,mainView;
  3. private int menuWidth = 0;
  4. private Scroller scroller;
  5. public SlideMenu(Context context, AttributeSet attrs) {
  6. super(context, attrs);
  7. init();
  8. }
  9. public SlideMenu(Context context) {
  10. super(context);
  11. init();
  12. }
  13. private void init(){
  14. scroller = new Scroller(getContext());
  15. }
  16. /**
  17. * 当1级的子view全部加载完调用,可以用初始化子view的引用,view.inflate完后
  18. * 注意,这里无法获取子view的宽高
  19. */
  20. @Override
  21. protected void onFinishInflate() {
  22. super.onFinishInflate();
  23. menuView = getChildAt(0);
  24. mainView = getChildAt(1);
  25. menuWidth = menuView.getLayoutParams().width;//可以通过这样获得
  26. }
  27. /**
  28. * widthMeasureSpec和heightMeasureSpec是系统测量SlideMenu时传入的参数,
  29. * 这2个参数测量出的宽高能让SlideMenu充满窗体,其实是正好等于屏幕宽高
  30. */
  31. //继承已有viewgroup就不需要这些了,相对布局也行,但是桢布局更快
  32. // @Override
  33. // protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  34. // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  35. //
  36. // int measureSpec = MeasureSpec.makeMeasureSpec(menuWidth, MeasureSpec.EXACTLY);
  37. //
  38. // //测量所有子view的宽高
  39. // //通过getLayoutParams方法可以获取到布局文件中指定宽高
  40. // menuView.measure(measureSpec, heightMeasureSpec);
  41. // //直接使用SlideMenu的测量参数,因为它的宽高都是充满父窗体
  42. // mainView.measure(widthMeasureSpec, heightMeasureSpec);
  43. //
  44. // }
  45. //为了侧边栏可以上下滑动菜单,可以根据移动的值处理掉事件,其他情况下不处理,交给主页面
  46. @Override
  47. public boolean onInterceptTouchEvent(MotionEvent ev) {
  48. switch (ev.getAction()) {
  49. case MotionEvent.ACTION_DOWN:
  50. downX = (int) ev.getX();
  51. break;
  52. case MotionEvent.ACTION_MOVE:
  53. int deltaX = (int) ( ev.getX()- downX);
  54. if(Math.abs(deltaX)>8){
  55. return true;
  56. }
  57. break;
  58. }
  59. return super.onInterceptTouchEvent(ev);
  60. // return super.onInterceptTouchEvent(ev);
  61. }
  62. /**
  63. * l: 当前子view的左边在父view的坐标系中的x坐标
  64. * t: 当前子view的顶边在父view的坐标系中的y坐标
  65. */
  66. @Override
  67. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  68. // Log.e("MAIN", "L: "+l+" t: "+t +" r: "+r + " b: "+b);
  69. menuView.layout(-menuWidth, 0, 0, menuView.getMeasuredHeight());
  70. mainView.layout(0, 0, r, b);
  71. }
  72. private int downX;
  73. @Override
  74. public boolean onTouchEvent(MotionEvent event) {
  75. switch (event.getAction()) {
  76. case MotionEvent.ACTION_DOWN:
  77. downX = (int) event.getX();
  78. break;
  79. case MotionEvent.ACTION_MOVE:
  80. int moveX = (int) event.getX();
  81. int deltaX = (int) ( moveX- downX);
  82. int newScrollX = getScrollX() - deltaX;//移动的距离,每次移动都不一样,所以需要计算下新的
  83. if(newScrollX<-menuWidth)newScrollX = -menuWidth;
  84. if(newScrollX>0)newScrollX = 0;
  85. Log.e("Main", "scrollX: "+getScrollX());
  86. scrollTo(newScrollX, 0);
  87. downX = moveX;
  88. break;
  89. case MotionEvent.ACTION_UP:
  90. //1.使用自定义动画
  91. // ScrollAnimation scrollAnimation;
  92. // if(getScrollX()>-menuWidth/2){
  93. // //关闭菜单
  94. //// scrollTo(0, 0);
  95. // scrollAnimation = new ScrollAnimation(this, 0);
  96. // }else {
  97. // //打开菜单
  98. //// scrollTo(-menuWidth, 0);
  99. // scrollAnimation = new ScrollAnimation(this, -menuWidth);
  100. // }
  101. // startAnimation(scrollAnimation);
  102. //2.使用Scroller
  103. if(getScrollX()>-menuWidth/2){
  104. // //关闭菜单
  105. closeMenu();
  106. }else {
  107. //打开菜单
  108. openMenu();
  109. }
  110. break;
  111. }
  112. return true;
  113. }
  114. private void closeMenu(){
  115. scroller.startScroll(getScrollX(), 0, 0-getScrollX(), 0, 400);//持续的时间
  116. invalidate();
  117. }
  118. private void openMenu(){
  119. scroller.startScroll(getScrollX(), 0, -menuWidth-getScrollX(), 0, 400);
  120. invalidate();
  121. }
  122. /**
  123. * Scroller不主动去调用这个方法
  124. * 而invalidate()可以掉这个方法
  125. * invalidate->draw->computeScroll
  126. */
  127. @Override
  128. public void computeScroll() {
  129. super.computeScroll();
  130. if(scroller.computeScrollOffset()){//返回true,表示动画没结束
  131. scrollTo(scroller.getCurrX(), 0);
  132. invalidate();
  133. }
  134. }
  135. /**
  136. * 切换菜单的开和关
  137. */
  138. public void switchMenu() {
  139. if(getScrollX()==0){
  140. //需要打开
  141. openMenu();
  142. }else {
  143. //需要关闭
  144. closeMenu();
  145. }
  146. }
  147. }

ScrollAnimation

  1. /**
  2. * 让指定view在一段时间内scrollTo到指定位置
  3. * @author Administrator
  4. *
  5. */
  6. public class ScrollAnimation extends Animation{
  7. private View view;
  8. private int targetScrollX;
  9. private int startScrollX;
  10. private int totalValue;
  11. public ScrollAnimation(View view, int targetScrollX) {
  12. super();
  13. this.view = view;
  14. this.targetScrollX = targetScrollX;
  15. startScrollX = view.getScrollX();
  16. totalValue = this.targetScrollX - startScrollX;
  17. int time = Math.abs(totalValue);
  18. setDuration(time);
  19. }
  20. /**
  21. * 在指定的时间内一直执行该方法,直到动画结束
  22. * interpolatedTime:0-1 标识动画执行的进度或者百分比
  23. * time : 0 - 0.5 - 0.7 - 1
  24. * value: 10 - 60 - 80 - 110
  25. * 当前的值 = 起始值 + 总的差值*interpolatedTime
  26. */
  27. @Override
  28. protected void applyTransformation(float interpolatedTime,
  29. Transformation t) {
  30. super.applyTransformation(interpolatedTime, t);
  31. int currentScrollX = (int) (startScrollX + totalValue*interpolatedTime);
  32. view.scrollTo(currentScrollX, 0);
  33. }
  34. }

MainActivity

  1. public class MainActivity extends Activity {
  2. private ImageView btn_back;
  3. private SlideMenu slideMenu;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. requestWindowFeature(Window.FEATURE_NO_TITLE);
  8. setContentView(R.layout.activity_main);
  9. btn_back = (ImageView) findViewById(R.id.btn_back);
  10. slideMenu = (SlideMenu) findViewById(R.id.slideMenu);
  11. btn_back.setOnClickListener(new OnClickListener() {
  12. @Override
  13. public void onClick(View v) {
  14. slideMenu.switchMenu();
  15. }
  16. });
  17. }
  18. }

来自为知笔记(Wiz)

时间: 2024-08-26 19:52:10

5.触摸事件、侧滑菜单的相关文章

侧滑菜单的使用和监听事件的设置

这段代码实现的功能是通过侧滑菜单来进行事件的改变,好累,今天这段代码真的伤人,本来思路是正确的,结果log打不出来,然后就默默的调试了很久,最后才可以的,言归正传,这里我们需要先下载侧滑菜单的三方框架,http://github.com/jfeinstein10/slidingmenu,这个是下载框架的地址,下载完成后,我们需要进行我们的项目和这个项目的链接, 我们导入这个项目的lib,然后在我们的项目下的perperity下添加库的关联,如果我们的suppeot.v4的包和他的包的版本不同的话

自定义控件:侧滑菜单

侧滑面板很其实现在容易找到成熟的第三方框架了,但是我们自己做一下,写一些核心代码,有助于我们的理解 1,简单介绍 写一个类继承ViewGroup 复写以下三个方法 onMeasure -> onLayout -> onDraw 1,测量左面板和主面板 左面板宽是指定的值240, 高度是屏幕高度 主面板宽高就是屏幕的宽高 2,摆放两个子控件 左面板的位置: 当前屏幕左边界0, 往左-240 主面板位置 : 当前控件的位置 3,处理触摸事件 (左右移动两个控件) 按下时, 获取按下的坐标downX

自定义SwipeLayout实现侧滑菜单

请尊重个人劳动成果,转载注明出处,谢谢! http://blog.csdn.net/amazing7/article/details/51768942 先看 SwipeLayout的效果图 图太多了,我这只上传一张,想看 listview和GridView效果的,和想看源码的 -> GitHub 怎么实现后面说,先说会废话. 最近整理以前的项目,那时有一个这样的需求,要在ExpandableListView的ChildView上实现 编辑和删除的侧滑菜单.我当时并没有用别人的框架,实现出来大概是

ViewDragHelper实践之仿Android官方侧滑菜单NavigationDrawer效果

相信经常使用移动应用的用户都很熟悉侧滑菜单栏, 下拉, 下弹, 上弹等应用场景, 几乎主流的移动应用无论IOS 还是Android都能看到. 2.3以前的时候, 很多第三方比如SlidingMenu, MenuDrawer, ActionbarSherlock等等都很大程度的丰富和深化了这种交互理念.能让小小的屏幕, 容纳更多的交互接口. 也是这种趋势, Android官方在v4终于推出了DrawerLayout. 表示对侧滑的重视与肯定. 唠叨到这了. 去看了DrawerLayout的源码和官

Android侧滑菜单和轮播图之滑动冲突

接手一个项目,有一个问题需要修改:轮播图不能手动滑动,手动滑动轮播图只会触发侧滑菜单. 猜测:viewpager控件(轮播图)的触摸事件被SlidingMenu控件(侧滑菜单,非第三方项目,乃是上个开发人员自定义的)拦截了. 基于这个猜测,我自定义一个ViewPager,重写dispatchTouchEvent.onInterceptTouchEvent和onTouchEvent,分别在这三个方法中打印log: 重写SlidingMenu的dispatchTouchEvent.onInterce

教你10行代码写侧滑菜单

原帖发表于传智播客黑马训程序员论坛,地址:http://bbs.itheima.com/thread-167442-1-1.html 先来看个侧滑菜单效果: 上面分别为:初始状态->滑动中->松开打开菜单 你造吗?看完本文章,写这种侧滑菜单,so easy for you! 你造吗?其实写这个侧滑菜单,只需要10行手写代码就能搞定! 你造吗?看完本文章,当你再听到产品说"我要这个效果"时,再也不会底气不足! 在Android开发中,自定义View效果是属于高级的部分.因为常

Android自定义控件——侧滑菜单

转载请注明出处:http://blog.csdn.net/allen315410/article/details/39397445 当我们打开某些应用的时候,总是会出现"侧滑菜单"这样的效果,至于这种侧滑菜单是谁首先创造出来的,已经不重要,但是侧滑菜单确实功能新颖,用户体验极好,以至于市面上很多很多的应用也纷纷加入侧滑菜单的效果,以下是我从应用市场上下载来的几个应用,随时截图发在这里,看看别人(大型互联网公司)都做这种效果,那么我们自己在没有很好的"创意"下,是不是

关于安卓开发实现侧滑菜单效果

学习出处:http://blog.csdn.net/guolin_blog/article/details/8714621 这里不转载内容了,按照自己理解写一篇 侧滑菜单效果 就是手机版QQ的左侧向右滑动出现菜单栏的那一种效果 实现原理.在一个Activity的布局中需要有两部分,一个是菜单(menu)的布局,一个是内容(content)的布局.两个布局横向排列,菜单布局在左,内容布局在右.初始化的时候将菜单布局向左偏移,以至于能够完全隐藏,这样内容布局就会完全显示在Activity中.然后通过

自定义Android侧滑菜单控件

package com.tenghu.sideslipmenu.view; import android.content.Context; import android.os.AsyncTask; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.VelocityTracker; import andr