zoukankan      html  css  js  c++  java
  • 触摸事件、侧滑菜单

    触摸事件

     
    侧滑菜单---
    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. publicclassSlideMenuextendsFrameLayout{
    2. privateView menuView,mainView;
    3. privateint menuWidth =0;
    4. privateScroller scroller;
    5. publicSlideMenu(Context context,AttributeSet attrs){
    6. super(context, attrs);
    7. init();
    8. }
    9. publicSlideMenu(Context context){
    10. super(context);
    11. init();
    12. }
    13. privatevoid init(){
    14. scroller =newScroller(getContext());
    15. }
    16. /**
    17. * 当1级的子view全部加载完调用,可以用初始化子view的引用,view.inflate完后
    18. * 注意,这里无法获取子view的宽高
    19. */
    20. @Override
    21. protectedvoid 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. publicboolean onInterceptTouchEvent(MotionEvent ev){
    48. switch(ev.getAction()){
    49. caseMotionEvent.ACTION_DOWN:
    50. downX =(int) ev.getX();
    51. break;
    52. caseMotionEvent.ACTION_MOVE:
    53. int deltaX =(int)( ev.getX()- downX);
    54. if(Math.abs(deltaX)>8){
    55. returntrue;
    56. }
    57. break;
    58. }
    59. returnsuper.onInterceptTouchEvent(ev);
    60. // return super.onInterceptTouchEvent(ev);
    61. }
    62. /**
    63. * l: 当前子view的左边在父view的坐标系中的x坐标
    64. * t: 当前子view的顶边在父view的坐标系中的y坐标
    65. */
    66. @Override
    67. protectedvoid 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. privateint downX;
    73. @Override
    74. publicboolean onTouchEvent(MotionEvent event){
    75. switch(event.getAction()){
    76. caseMotionEvent.ACTION_DOWN:
    77. downX =(int) event.getX();
    78. break;
    79. caseMotionEvent.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. caseMotionEvent.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. returntrue;
    113. }
    114. privatevoid closeMenu(){
    115. scroller.startScroll(getScrollX(),0,0-getScrollX(),0,400);//持续的时间
    116. invalidate();
    117. }
    118. privatevoid 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. publicvoid computeScroll(){
    129. super.computeScroll();
    130. if(scroller.computeScrollOffset()){//返回true,表示动画没结束
    131. scrollTo(scroller.getCurrX(),0);
    132. invalidate();
    133. }
    134. }
    135. /**
    136. * 切换菜单的开和关
    137. */
    138. publicvoid 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. publicclassScrollAnimationextendsAnimation{
    7. privateView view;
    8. privateint targetScrollX;
    9. privateint startScrollX;
    10. privateint totalValue;
    11. publicScrollAnimation(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. protectedvoid 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. publicclassMainActivityextendsActivity{
    2. privateImageView btn_back;
    3. privateSlideMenu slideMenu;
    4. @Override
    5. protectedvoid 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(newOnClickListener(){
    12. @Override
    13. publicvoid onClick(View v){
    14. slideMenu.switchMenu();
    15. }
    16. });
    17. }
    18. }
     





  • 相关阅读:
    docker 安装mysql
    Java web项目搭建系列之二 Jetty下运行项目
    Java web项目搭建系列之一 Eclipse中新建Maven项目
    Maven 添加其他Maven组件配置问题
    C# 中定义扩展方法
    Oracle 函数
    【Webservice】2 counts of IllegalAnnotationExceptions Two classes have the same XML type name
    Linux精简版系统安装网络配置问题解决
    Rsync 故障排查整理
    Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.
  • 原文地址:https://www.cnblogs.com/sixrain/p/5041931.html
Copyright © 2011-2022 走看看