Android 实现滑动的六种方式

作者:FranzLiszt1847 时间:2021-12-05 08:27:48 

目录
  • 1、效果视频

  • 2、剖析Android坐标系

  • 3、实现方式

    • 3.1 layout

    • 3.2 scrollBy

    • 3.3 offsetLeftAndRight offsetTopAndButton

    • 3.4 LayoutParams

    • 3.5 Scroller

    • 3.6 平移动画

1、效果视频

Android 实现滑动的六种方式

2、剖析Android坐标系

滑动的本质是移动,滑动的原理就是通过不断的改变View的坐标而实现。

Android 实现滑动的六种方式

Android系统提供了很多方法获取坐标值,可以将其分为两种类别,具体如下:

View 提供的获取坐标的方法:

  • getTop():获取到的是View自身的顶边到其父布局顶边的距离

  • getLeft():获取到的是View自身的左边到其父布局左边的距离

  • getRight():获取到的是View自身的右边到其父布局左边的距离

  • getBottom():获取到的是View自身的底边到其父布局顶边的距离

MotionEvent 提供的方法:

  • getX():获取点击事件距离控件左边的距离,即视图坐标

  • getY():获取点击事件距离控件顶边的距离,即视图坐标

  • getRawX():获取点击事件距离整个屏幕左边的距离,即绝对坐标

  • getRawY():获取点击事件距离整个屏幕顶边的距离,即绝对坐标

3、实现方式

3.1 layout

使用绝对坐标系,每次执行移动逻辑后需要重新设置初始化坐标


@Override
   public boolean onTouchEvent(MotionEvent event) {
       int rawX = (int) (event.getRawX());
       int rawY = (int) (event.getRawY());
               switch (event.getAction()){
           case MotionEvent.ACTION_DOWN:
               lastX = rawX;
               lastY = rawY;
               break;
           case MotionEvent.ACTION_MOVE:
               int offsetX = rawX - lastX;
               int offsetY = rawY - lastY;
              layout( getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY );
              lastX = rawX;
              lastY = rawY;
               break;
           case MotionEvent.ACTION_UP:
               break;

}
       return true;
   }

3.2 scrollBy


   @Override
   public boolean onTouchEvent(MotionEvent event) {
       int x = (int) event.getX();
       int y = (int) event.getY();
       switch (event.getAction()) {
           case MotionEvent.ACTION_DOWN:
               lastX = x;
               lastY = y;
               break;
           case MotionEvent.ACTION_MOVE:
               int offsetX = x - lastX;
               int offsetY = y - lastY;
               ((View) getParent()).scrollBy( -offsetX, -offsetY );
               break;
           case MotionEvent.ACTION_UP:
               break;

}
       return true;
   }

3.3 offsetLeftAndRight offsetTopAndButton


@Override
   public boolean onTouchEvent(MotionEvent event) {
       int x = (int) event.getX();
       int y = (int) event.getY();
       switch (event.getAction()){
           case MotionEvent.ACTION_DOWN:
               lastX = x;
               lastY = y;
               break;
           case MotionEvent.ACTION_MOVE:
               int offsetX = x - lastX;
               int offsetY = y - lastY;
              offsetLeftAndRight( offsetX );
              offsetTopAndBottom( offsetY );
               break;
           case MotionEvent.ACTION_UP:
               break;

}
       return true;
   }

3.4 LayoutParams

通过getLayoutParams()获取LayoutParams时,需要根据不同的父类型使用设置不同的类型,比如父布局为LinearLayout则设置类型为 LinearLayout.LayoutParams


   @Override
   public boolean onTouchEvent(MotionEvent event) {
       int x = (int) event.getX();
       int y = (int) event.getY();
       switch (event.getAction()){
           case MotionEvent.ACTION_DOWN:
               lastX = x;
               lastY = y;
               break;
           case MotionEvent.ACTION_MOVE:
               int offsetX = x - lastX;
               int offsetY = y - lastY;
               LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)getLayoutParams();
               layoutParams.leftMargin = getLeft()+offsetX;
               layoutParams.topMargin = getTop()+offsetY;
               setLayoutParams( layoutParams );
               break;
           case MotionEvent.ACTION_UP:
               break;

}
       return true;
   }

更方便的是直接使用ViewGroup,不需要判断父布局类型


 ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams();
               layoutParams.leftMargin = getLeft()+offsetX;
               layoutParams.topMargin = getTop()+offsetY;
               setLayoutParams( layoutParams );

3.5 Scroller

初始化Scroller:


scroller = new Scroller( context );

重写computeScroll()方法

使用computeScrollOffset()判定是否完成了整个滑动:


  @Override
   public void computeScroll() {
       if (scroller.computeScrollOffset()) {
           ((View) getParent()).scrollTo( scroller.getCurrX(), scroller.getCurrY() );
           invalidate();
       }
   super.computeScroll();
   }

@Override
   public boolean onTouchEvent(MotionEvent mv) {
       View parent = (View) getParent();
       switch (mv.getAction()) {
           case MotionEvent.ACTION_DOWN:
               lastX = (int) mv.getX();
               lastY = (int) mv.getY();
               break;
           case MotionEvent.ACTION_MOVE:
               int upX = (int) (mv.getX() - lastX);
               int upY = (int) (mv.getY() - lastY);
               parent.scrollBy( -upX, -upY );
               break;
           case MotionEvent.ACTION_UP:
               scroller.startScroll( parent.getScrollX(), parent.getScrollY(), -parent.getScrollX(), -parent.getScrollY(), 1000 );
               invalidate();
               break;
       }
       return super.onTouchEvent( mv );
   }

3.6 平移动画

效果视频:

Android 实现滑动的六种方式


private void InitAnimation(){
       animation = new TranslateAnimation( 0,200,0,200 );
       animation.setDuration( 1000 );
   }


moveButton.startAnimation( animation );

来源:https://blog.csdn.net/News53231323/article/details/121208702

标签:Android,滑动
0
投稿

猜你喜欢

  • android ItemTouchHelper实现可拖拽和侧滑的列表的示例代码

    2023-08-14 14:51:51
  • jdk动态代理源码分析过程

    2023-03-01 05:05:59
  • Android图片处理:识别图像方向并显示实例教程

    2023-02-11 08:01:07
  • C#对Xamarin框架进行数据绑定

    2022-04-07 23:36:50
  • elasticsearch集群发现zendiscovery的Ping机制分析

    2021-05-25 05:40:55
  • java中的基础运算符

    2022-06-23 04:19:38
  • java Iterator.remove()实例方法分析

    2022-05-01 15:56:01
  • 基于spring cloud多个消费端重复定义feign client的问题

    2022-09-18 11:34:23
  • Android读取资源文件的方法

    2022-09-25 22:11:53
  • Android组件之服务的详解

    2021-10-14 00:05:30
  • C#中 Json 序列化去掉null值的方法

    2022-02-02 12:13:52
  • RocketMQ源码分析之Broker过期消息清理机制

    2023-06-10 15:47:43
  • Android 获取 usb 权限的两种方法

    2022-01-06 14:37:06
  • java之Object类用法实例

    2023-11-05 04:14:26
  • Java抽象类和接口的区别详情

    2023-05-23 20:09:59
  • Java实现简单班级管理系统

    2023-01-07 16:20:29
  • 老生常谈Java 网络编程 —— Socket 详解

    2023-07-12 16:32:54
  • Java爬虫范例之使用Htmlunit爬取学校教务网课程表信息

    2021-07-17 00:52:51
  • C#自定义处理xml数据类实例

    2022-07-02 11:00:39
  • RocketMQ4.5.2 修改mqnamesrv 和 mqbroker的日志路径操作

    2023-11-28 14:03:18
  • asp之家 软件编程 m.aspxhome.com