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. }
     





  • 相关阅读:
    串口调试助手
    自己动手编写俄罗斯方块
    ASP.NET Core log4net
    ASP.NET Core读取配置文件
    ASP.NETCore3 MVC
    ASP.NETCore2C#7.0新语法
    ASP.NETCore1C#6.0新语法
    C#加密解密
    前端通用的滚动条样式
    C# 106 短信发送
  • 原文地址:https://www.cnblogs.com/sixrain/p/5041931.html
Copyright © 2011-2022 走看看