View获取位置

本文搬运了以下作者的内容加以整理,仅仅方便自己查阅:
1.CSDN博主「chaseDreamer_」的原创文章
原文链接:https://blog.csdn.net/chasedreamer_/article/details/97262581
2.《Android开发艺术探索》

1.getLocationInWindow

这个方法是将view的左上角座标存入数组中.此座标是相对当前activity而言.
若是普通activity,则y座标为可见的状态栏高度 + 可见的标题栏高度 + view左上角到标题栏底部的距离。
可见的意思是:在隐藏了状态栏/标题栏的情况下,它们的高度以0计算.
若是对话框式的activity,则y座标为可见的标题栏高度+view到标题栏底部的距离,此时是无视状态栏的有无的。

int[] position = new int[2];  
textview.getLocationInWindow(position);  
System.out.println("getLocationInWindow:" + position[0] + "," + position[1]);  

2.getLocationOnScreen

这个方法跟上面的差不多,也是将view的左上角座标存入数组中.但此座标是相对整个屏幕而言。x、y座标为view左上角到屏幕顶部的距离。

int[] position = new int[2];  
textview.getLocationOnScreen(position);  
System.out.println("getLocationOnScreen:" + position[0] + "," + position[1]);  

3.View中相对座标

View左上角相对于父容器的横向偏移量

getTranslationX()  
public float getTranslationX ()

View左上角相对于父容器的竖向偏移量

getTranslationY()
public float getTranslationY ()

View原始左上角的Y座标的值,不管View怎么移动,这个值不会发生改变

getTop () 
public final int getTop ()

View原始左上角X座标的值,同上,也是不会改变

getLeft()    
public final int getLeft ()

View原始右下角Y座标的值,同上,也是不会改变

getBottom()  
public final int getBottom ()

View原始右下角X座标的值,同上,也是不会发生改变

getRight()  
public final int getRight ()

获取View左上角的X座标,相当于getLeft()+getTranslationX()

getX() 
public float getX ()

获取View左上角的Y座标,相当于getTop+getTranslationY()

getY() 
public float getY()

view围绕其旋转和缩放的点的X位置,在view的动画中会用得到

getPivotX()
public float getPivotX ()

view围绕其旋转和缩放的点的Y位置

getPivotY()  
public float getPivotY ()

获取View的中心点座标
如果想要获取View中心点的座标,首先你需要知道它某个角的座标和他的长和宽

int top = view.getTop();
int left = view.getLeft();
 int right = view.getRight();
 int bottom = view.getBottom();
	
//View的 宽
int viewWidth = right - left;
//View的 高
int viewHeight = bottom - top;
//中心点的Y座标
int centerY = top + viewHeight/2;
//中心点的X座标
int centerX = left + viewWidth/2;

4.检测View是否绘制成功,获取view的座标

1.view.post(runnable) 推荐!
通过post可以将一个runnable投递到消息队列的尾部,然后等待Looper调用此runnable的时候,View也已经初始化好了。这里要注意,view.post的前提是view没有被销毁,对于使用了lottie库实现的view要慎用

  protected void onStart() {
        super.onStart();
        view.post(new Runnable() {
                @Override
                public void run() {
                        int width = view.getMeasuredWidth();
                        int height = view.getMeasuredHeight();
                }
        });
    }

2. Activity/View#onWindowFocusChanged
onWindowFocusChanged这个方法的含义是:View已经初始化完毕了,宽/高已经准备好了,这个时候去获取宽/高是没问题的。需要注意的是,onWindowFocusChanged会被调用多次,当Activity的窗口得到焦点和失去焦点时均会被调用一次。具体来说,当Activity继续执行和暂停执行时,onWindowFocusChanged均会被调用,如果频繁地进行onResume和onPause,那么onWindowFocusChanged也会被频繁地调用。

public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
                int width = view.getMeasuredWidth();
                int height = view.getMeasuredHeight();
        }
}

3.ViewTreeObserver
使用ViewTreeObserver的众多回调可以完成这个功能,比如使用OnGlobalLayoutListener这个接口,当View树的状态发生改变或者View树内部的View的可见性发现改变时,onGlobalLayout方法将被回调,因此这是获取View的宽/高一个很好的时机。需要注意的是,伴随着View树的状态改变等,onGlobalLayout会被调用多次。
一定要注意,OnGlobalLayoutListener用完要及时移除

view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
 protected void onStart() {
        super.onStart();
        ViewTreeObserver observer = view.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
                        view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        int width = view.getMeasuredWidth();
                        int height = view.getMeasuredHeight();
                }
        });
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章