码迷,mamicode.com
首页 > 其他好文 > 详细

5.触摸事件、侧滑菜单

时间:2015-12-12 23:19:09      阅读:565      评论:0      收藏:0      [点我收藏+]

标签:

触摸事件
技术分享
技术分享

技术分享
侧滑菜单---
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. }





5.触摸事件、侧滑菜单

标签:

原文地址:http://www.cnblogs.com/liuyu0529/p/5041931.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!