View系列笔记(一)----基础概念知识

[TOC]

声明:此系列的部分内容出自《Android开发艺术探索》一书,是我当初学习时候的一些笔记和总结,在这里留个记录。
  View是android中所有控件的基类。

位置参数

在Android系统中,左上角为坐标原点,x和y轴正方向分别是往右和下。View的位置由它的4个顶点来决定,即top,left,right,bottom。需要注意的是这4个点是相对坐标,相对于view的父容器来说的。获取方法:

  • top: getTop()
  • left: getLeft()
  • right: getRight()
  • bottom: getBottom()

从Android3.0开始,View增加了4个额外的参数:x,y,translationX,translationY。其中x和y指view左上角的坐标,translationX和translationY指view左上角相对于父容器的偏移量。这4个参数也都是相对坐标,他们之间的相互关系如下:

  • x = left + translationX;
  • y = top + translationY;

即:在view发生平移的过程中,left和top始终是不变的,指view原始位置的左上角坐标,发生改变的只是x,y,translationX,translationY这4个参数。

触摸事件

MotionEvent

手指的触摸事件一般可以分为两种(姑且把单击和长按当成一种,滑动和多点触控当成一种吧,起码触发的事件是差不多的):

  • 手指按下,不滑动,放开:DOWN--->UP。
  • 手指按下,滑动一段距离,再松手:DOWN--->MOVE--->...--->MOVE--->UP。

通过MotionEvent对象我们可以得到点击位置的坐标:

  • getX()和getY():得到的是相对当前view左上角的坐标。
  • getRawX()和getRawY():得到的是相对手机屏幕左上角的坐标。

TouchSlop

即系统所能识别出的被认为是滑动的最小距离。常量,和硬件设备有关,可以通过ViewConfiguration.get(context).getScaledTouchSlop()得到,手指移动小于这个值得话则认为这次操作不是滑动。

VelocityTracker

用来测量某个触摸事件的速度。

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        /**
         * 某个触摸时间的速度测量:
         * 1.通过obtain()方法获得velocityTracker变量,并添加需要测量的事件
         * 2.通过computeCurrentVelocity计算速度(参数单位为ms),再通过getter方法获取速度值(右下滑为正数,反之为负数)
         * 3.释放velocityTracker对象。
         */
        VelocityTracker velocityTracker = VelocityTracker.obtain();
        velocityTracker.addMovement(event);

        velocityTracker.computeCurrentVelocity(1000);//秒速
        int v_x = (int) velocityTracker.getXVelocity();
        int v_y = (int) velocityTracker.getYVelocity();

        LogUtils.i(TAG,"\t\tX:" + v_x + "\t\tY:" + v_y);

        velocityTracker.recycle();

        return true;
    }
    
02-17 11:26:55.483 27154-27154/lxf.androiddemos I/TestView:         X:5656      Y:1203
02-17 11:26:55.500 27154-27154/lxf.androiddemos I/TestView:         X:6255      Y:1202
02-17 11:26:55.509 27154-27154/lxf.androiddemos I/TestView:         X:0     Y:0
02-17 11:26:55.510 27154-27154/lxf.androiddemos I/TestView:         X:0     Y:0
02-17 11:27:01.207 27154-27154/lxf.androiddemos I/TestView:         X:0     Y:0
02-17 11:27:01.248 27154-27154/lxf.androiddemos I/TestView:         X:-421      Y:49
02-17 11:27:01.265 27154-27154/lxf.androiddemos I/TestView:         X:-2978     Y:372
02-17 11:27:01.282 27154-27154/lxf.androiddemos I/TestView:         X:-3426     Y:426

GestureDetector

手势检测,用来辅助检测用户的滑动、单击、双击、长按等行为。

//1.实现OnGestureListener接口
public class TestView extends View implements GestureDetector.OnGestureListener{
//2.获得GestureDetector对象,
gestureDetector = new GestureDetector(getContext(),this);
//如果要监听双击,可以实现DoubleTapListener接口
gestureDetector.setOnDoubleTapListener(mDoubleTapListener);
...
//3.接管onTouchEvent(event)方法。
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
//4.在接口的相应回调方法中实现自己的逻辑。
...
}

View的滑动

scrollTo/scrollBy

scrollBy内部实际上就是调用的scrollTo方法,它实现了view基于当前位置的相对滑动,而scrollTo是相对于初始位置滚动某段距离,可以变向理解为绝对滑动。

    public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

在滑动过程中,mScrollX的值总是等于view的左边缘(left)和view的内容的左边缘在水平方向上的距离,mScrollY同理。scrollTo/scrollBy只能改变view的内容位置而不能改变view在布局中的位置。

使用动画

使用动画使view平移的方式有两种:

  • 补间动画:实际上是对view的影像进行操作,并不会改变view本身的位置、内容等参数。
TranslateAnimation animation = new TranslateAnimation(0,100,0,0);
setAnimation(animation);
animation.start();
  • 属性动画:直接操作view的属性,可以改变view自身。
ObjectAnimator.ofInt(targetView,"translationX",0,100).setDuration(500).start();

改变LayoutParams

        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
        params.leftMargin += 100;
        setLayoutParams(params);
//      或requestLayout();

弹性滑动

使用Scroller

Scroller的典型用法:

scroller = new Scroller(getContext());

    private void smoothScrollTo(int x, int y) {
        int scrollX = getScrollX();
        int delayX = x - scrollX;
        scroller.startScroll(scrollX, 0, delayX, 0, 1000);//仅仅保存相应参数
        invalidate();//draw方法中会调用computeScroll
    }

    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate();
        }
    }

Scroller本身并不能使View滑动,它需要配合View的computeScroll方法才能实现弹性滑动的效果。它不断让view重绘,每一次重绘距离view的起始滑动会有一个时间间隔,通过这个时间间隔Scroller可以得到view的当前滑动位置,通过scrollTo()完成滑动。

使用属性动画

值动画:其实属性动画的根本就是属性值的改变

        ValueAnimator animator = ValueAnimator.ofFloat(0,1).setDuration(1000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float flag = animation.getAnimatedFraction();
                scrollTo(startX + (int)(delayX * flag),0);
            }
        });
        animator.start();

其实所谓弹性滑动,就是将一次滑动分成了若干个短距离滑动。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容