zoukankan      html  css  js  c++  java
  • View坐标分析汇总

    view 坐标分析


    参考
    View事件分析汇总

    一. 移动View的7种方法

    1.Layout

    layout(getLeft()+50,getTop()+100,getRight()+50,getBottom()+100);
    

    getLeft()等值改变。(这里指的有getLeft/getRight/getTop/getBottom)

    2.offsetLeftAndRight, offsetTopAndBottom

    offsetLeftAndRight(50);
    offsetTopAndBottom(100);
    

    getLeft()等值改变。

    3.修改LayoutParams

    ViewGroup.MarginLayoutParams lp =(ViewGroup.MarginLayoutParams)getLayoutParams();
    lp.leftMargin = getLeft()+50;
    lp.topMargin = getTop()+100;
    setLayoutParams(lp);
    

    getLeft()等值不改变。

    4.scrollTo

    ((View)getParent()).scrollTo(-50,-100);
    

    只会移动一次。getLeft()等值不改变。

    5.scrollBy

    scrollBy的实现为:

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

    scrollBy的使用:

    ((View)getParent()).scrollBy(-50,-100);
    

    getLeft()等值不改变。
    使用scrollTo/scrollBy时候,要注意到

    1.移动计算值 = 最开始点坐标 - 最后移动到的坐标
    2.((View)getParent()),View的scrollTo/scrollBy移动的对象是View的Content,所以在这里我们先取得要移动对象的parent,再进行移动。如果不加的话,以TextView为例子,则移动的将会是文字内容。
    3.如果在ViewGroup中使用scroll,则移动的将是所有的子View.

    6.属性动画

    AnimatorSet set = new AnimatorSet();
    set.playTogether(
            ObjectAnimator.ofFloat(this, "translationX", 50),
            ObjectAnimator.ofFloat(this,"translationY", 100));
    set.start();
    

    这种方法看效果更加丝滑。
    getLeft()等值不改变。

    7.位移动画

    TranslateAnimation anim = new TranslateAnimation(0,50,0,100);
    anim.setFillAfter(true);
    startAnimation(anim);
    

    getLeft()等值不改变。

    二.View移动动画的实现

    1.使用layout方法

    首先在继承View的类中定义两个变量用于保存前一次的公位置。

    private int lastX;
    private int lastY;
    

    再重写事件处理方法,注意,这里返回的值为true,表示事件已经处理过了。view中默认返回的是false。
    如果使用event的getX/getY方法:

     @Override
        public boolean onTouchEvent(MotionEvent event) {
            int x = (int)event.getX();
            int y = (int)event.getY();
    
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Logger.d("Action down");
                    lastX = x;
                    lastY = y;
                    break;
                case MotionEvent.ACTION_MOVE:
                    Logger.d("Action move");
                    int offsetX = x - lastX;
                    int offsetY = y - lastY;
                    layout(getLeft()+offsetX,
                            getTop()+ offsetY,
                            getRight() + offsetX,
                            getBottom()+ offsetY);
                    break;
                case MotionEvent.ACTION_UP:
                    Logger.d("Action up");
                    break;
            }
            return true;
        }
    

    如果使用event的getRawX/getRawY,如下:

    @Override
        public boolean onTouchEvent(MotionEvent event) {
            int rawX = (int)event.getRawY();
            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
                    );
                    break;
                    lastX = rawX;
                    lastY = rawY;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    
    • 使用offsetLeftAndRight与ViewGroup.MarginLayoutParams方法与上面完全一样。
    • 使用getRawX/getRawY时,要注意不同,原因在于两者得到坐标区别。

    2.使用scrollTo/scrollBy方法

    如果是使用scrollBy,与上面其它方法不同的是,要注意最后有一个重新获取所在的点。

    @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;
                    ((View)getParent()).scrollBy(-offsetX,-offsetY);
                    lastX = (int)event.getRawX();
                    lastY = (int)event.getRawY();
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    

    这里,如果在这个View的parent中还有其它的View,也会一起滑动。

    2.Scroller的平滑移动

    与scrollTo/ScrollBy的移动都是瞬间完成不同,Scroller类提供了一种平滑移动的效果,但是两者原理相同。使用步骤:

    1) 初始化Scroller

    在构造方法中

    mScroller = new Scroller(context);
    

    2) 重写computeScroll()

    进行模拟移动,此方法在startScroll后调用。

    @Override
        public void computeScroll() {
            super.computeScroll();
            //This is called in draw
            if(mScroller.computeScrollOffset()){
                ((View)getParent()).scrollTo(
                        mScroller.getCurrX(),//current scroll location
                        mScroller.getCurrY());
                invalidate();//invalidate->draw->computeScroll
            }
        }
    

    computeScrollOffset是判断是否完成了整个滑动过程。

    3) startScroll开启模拟过程

    通过startScroll方法来开启整个平滑移动过程。
    在获取坐标的时候,我们通过 getScrollX/getScrollY来获取父视图中content所滑动到的点的坐标。
    在onTouchEvent中:

    case MotionEvent.ACTION_UP:
                    Log.d(TAG,"Action up");
                    //getScrollX():Return the scrolled position of this view
                    View viewGroup = (View)getParent();
                    mScroller.startScroll(
                            viewGroup.getScrollX(),
                            viewGroup.getScrollY(),
                            -viewGroup.getScrollX(),
                            -viewGroup.getScrollY()
                    );
                    invalidate();
                    break;
    

    3.ViewDragHelper

    通过ViewDragHelper基本可以实现各种不同的滑动等。
    使用方法见
    ViewDragHelper使用方法

  • 相关阅读:
    纯css3实现的超炫checkbox复选框和radio单选框
    css3和jquery实现的可折叠导航菜单(适合手机网页)
    HTML5 Canvas 梦幻的文字飞扬动画教程
    纯css3实现的圆形旋转分享按钮
    纯css3实现的创意图片放大镜
    java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView
    python的range函数与切片操作符
    python简单基础代码
    android笔记 : Content provider内容提供器
    android笔记:Service
  • 原文地址:https://www.cnblogs.com/chuiyuan/p/5519344.html
Copyright © 2011-2022 走看看