zoukankan      html  css  js  c++  java
  • View初探

    View初探

    学习自

    《Android开发艺术探索》

    View漫谈

    Activity构成了我们的界面但是知识一个空壳子,Activity与View相结合才构成了我们丰富多彩的界面,并且为了满足一些特殊的功能,Android提供的标准控件并不能满足我们的需要,这时候我们就需要自己定义View来满足我们的需求了。所以View是我们整个Android体系中最重要的一块之一。

    View的体系

    View 类是所有的View的基类,是所有的控件类的一个抽象,代表着一个控件,不管是Button还是LinerLayout都是一个View.下图是View类的继承层次结构。

    image.png | left | 802x400

    View的位置参数

    Android中定位一个View的位置有两种标准,这两个标准之间是可以相互转换的。

    TopLeftRightBttom

    View的位置由四个顶点来确定,分别是

    • top 左上角纵坐标
    • left 左上角总坐标
    • right 右下角横坐标
    • bottom 右下角纵坐标
      PS: 这四个点的坐标都是相对于父容器的

    image.png | left | 631x455
    我们可以轻易地通过坐标来计算出View的宽度和高度

    var left = openBtn.left
    var right = openBtn.right
    var top = openBtn.top
    var bottom = openBtn.bottom
    
    var width = right - left
    var height = bottom - top
    

    Android 3.0 提供的一种标准

    从Android3.0 开始,View类中提供了几个新的参数来供我们来定位View的坐标,他们分别是

    • x view 的X轴的坐标
    • y view 的Y轴的坐标
    • translationX 左上角相对于父容器X轴的偏移量, 默认值为0
    • translationY 左上角相对于父容器Y轴的偏移量,默认值为0

    PS: translationX和translationY 的默认值得问题需要详细说明一下,比如说现在界面上有一个是Button,该Button的坐标为(50,50),那么这次Button的translationX和translationY 不是50而是0.0.

    MotionEvent

    MotionEvent是手指接触屏幕收所产生了一些列事件,常见的有一下几种

    • ACTION_DOWN 手指接触屏幕
    • ACTION_MOVE 手指在屏幕上移动
    • ACTION_UP 手指从屏幕上松开

    获取MotionEvent

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event != null) {
            var action = when (event.action) {
                MotionEvent.ACTION_DOWN -> "Action_Down"
                MotionEvent.ACTION_MOVE -> "Action_Move"
                MotionEvent.ACTION_UP -> "Action_UP"
                else -> "unknown"
            }
            L.e(action)
        }
        return super.onTouchEvent(event)
    }
    

    MotionEvent的常用方法

    通过MotionEvent对象我们可以获取到点击事件发生的位置,MotionEvent对象提供了以下的方法

    • getX 获取相对于当前View的左上角的X坐标
    • getY 获取相对于当前View的左上角的Y坐标
    • getRawX 获取相当于屏幕左上角的X坐标
    • getRawY 获取相当于屏幕左上角的Y坐标

    TouchSlop

    TouchSlop是一个 常量 ,该常量值的是__滑动的最小距离__,如果手指在屏幕上滑动的时候,两次滑动间的距离小于此值的话,那么系统不认为此次动作是滑动动作。该常量与__设备有关__。通过此常量我们可以过滤一些无效的滑动,来提高用户体验。
    通过 ViewConfiguration.get(this).scaledTouchSlop 来获取。

    VelocityTracker 速度追踪器

    VelocityTracker(速度追踪器),用于追踪手指滑动时的速度(水平方向/垂直方向)。

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        //获取到VelocityTracker对象,并与MotionEvent关联起来
        var tracker = VelocityTracker.obtain()
        tracker.addMovement(event)
        
        //!!!在获取速度之前必须先计算一下
        //1000 这个值指定的时单位时间,用来计算速度
        tracker.computeCurrentVelocity(1000)
        var xVelocity = tracker.xVelocity
        var yVelocity = tracker.yVelocity
        
        L.e("xVelocity=$xVelocity")
        L.e("yVelocity=$yVelocity")
        return super.onTouchEvent(event)
    
       //回收资源
       tracker.clear()
       tracker.recycle()
    }
    

    请注意在获取滑动的速度之前,执行了这么一句代码 tracker.computeCurrentVelocity(1000) ,只有调用了此方法后,获取的速度值才是正确的,这也是必须的,系统不能时时刻刻来计算滑动的速度,所以当我们需要获取滑动的速度的时候,我们需要提前告知系统。

    注意速度可以为负数,当X轴的滑动方向是从左到右的时,速度为正数,反之则为负数,Y中的情况也类似。

    GestureDetector 手势监听者

    GestureDetector用于监听用户的一些复杂得手势动作,比如说 抛掷,滑动,双击等。

    class MainActivity : AppCompatActivity() {
    
        lateinit var currentGestureDetector: GestureDetector
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            //设置手势事件
            currentGestureDetector = GestureDetector(this, object : GestureDetector.OnGestureListener {
                override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
                    return true
                }
    
                override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
                    return true
                }
            })
        }
    
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            if (event == null)
                return false
            this.currentGestureDetector.onTouchEvent(event)
            return super.onTouchEvent(event)
        }
    }
    
    

    手势接口相关的方法

    Name Description Belong to
    onDown 手指按下 OnGestureListener
    onShowPress 手指轻轻触摸屏幕,由一个ACTION_DOWN触发,和onDown相比,此方法更强调没有松开或者拖拽的状态 OnGestureListener
    onSingleTapUp 单击 OnGestureListener
    onScroll 拖拽 OnGestureListener
    onLongPress 长按 OnGestureListener
    onFling 抛掷,按下屏幕后快速滑动 OnGestureListener
    onDoubleTap 双击 OnDoubleTapListener
    onSingleTapConfirmed 严格的单击行为,如果触发了此方法,那么此次行为只能是单词,而不是双击操作中的一次单击 OnDoubleTapListener
    onDoubleTapEvent 表示发生了双击行为 OnDoubleTapListener

    最佳实践

    使用GestureDetector来处理手势的动作,有时候未免太过繁琐,如果只是简单的动作直接就可以通过MotionEvent来处理,总结如下

    • 如果只是监听滑动相关的时间,建议在onTouchEvent中自己实现
    • 如果是和双击相关的,建议是用GestureDetector来实现

    End

    本文大致介绍了一下View和View的常用的事件,下一章将会着手学习一下View的滑动,如果文中有任何谬误敬请斧正。

  • 相关阅读:
    配置 jvisualvm 监控Java虚拟机
    配置 IDEA 远程连接应用服务器
    Java虚拟机知识点【工具】
    Java虚拟机知识点【参数】
    Java虚拟机知识点【GC】
    Java虚拟机知识点【方法调用】
    Java虚拟机知识点【字节码】
    [NOIP2017]逛公园 题解
    [CSP-S模拟测试72]题解
    [CSP-S模拟测试69]题解
  • 原文地址:https://www.cnblogs.com/slyfox/p/9246034.html
Copyright © 2011-2022 走看看