Android view 坐标

本文介绍了Android中获取视图坐标的不同方法,包括getLocationOnScreen、getLocationInWindow、getLeft、getTop等,并通过实例代码展示了它们的区别。实验结果显示getLocationInWindow返回窗口内的坐标,而getLocationOnScreen返回屏幕绝对坐标。getLeft等函数返回相对于父视图的坐标。最后,探讨了与触摸事件相关的getX、getY、getRawX和getRawY,指出它们分别对应于相对于视图和屏幕的坐标。

android获取控件的坐标有如下几个方法:
1 getLocationOnScreen ,计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是包括了通知栏的高度)
2 getLocationInWindow ,计算该视图在它所在的widnow的坐标x,y值
3 getLeft , getTop, getBottom, getRight, 这一组是获取相对在它父亲里的坐标
4 上面的是在view里面提供的方法,在motionEvent里面也提供了几个方法:getX,getRawX,getY,getRawY
测试代码:

public class MainActivity extends AppCompatActivity {

//    @BindView(R.id.LocationInWindow) Button _btn_locationWindow;
//    @BindView(R.id.locationOnScreen) Button _btn_locationScreen;
    @BindView(R.id.textView) TextView _text_view;
    String tag = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.setDebug(BuildConfig.DEBUG);
        ButterKnife.bind(this);
    }


    @OnClick(R.id.locationOnScreen)
    public void onClick(Button button){
        int[] location = new int[2];
        _text_view.getLocationOnScreen(location);
        Log.d(tag,"location x is " + Integer.toString(location[0]) + " y is" + Integer.toString(location[1]) );
    }

    @OnClick(R.id.LocationInWindow)
    public void window(Button button){
        int[] location = new int[2];
        _text_view.getLocationInWindow(location);
        Log.d(tag,"location x is " + Integer.toString(location[0]) + " y is" + Integer.toString(location[1]) );
    }
}

上面这一段代码运行,把textview放在哪个位置得到的值都是一样的,说明如果直接布局在layout上面两个函数的值是一样的。
然后我重新定义了一个dialog,因为dialog是继承与window的,在来看看,代码如下:

public class MyDialog extends Dialog {

    Context context;
    @BindView(R.id.txt_pos)
    TextView txt_pos;
    public MyDialog(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;

    }
    public MyDialog(Context context, int theme){
        super(context, theme);
        this.context = context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.dialogtest);
        ButterKnife.bind(this);
    }

    @Override
    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {

    }

    @OnClick(R.id.btn_one)
    public void windowPos(Button button){
        int[] location = new int[2];
        txt_pos.getLocationInWindow(location);
        Log.d("dialog","window x is "  + Integer.toString(location[0]) + "y is " + Integer.toString(location[1]));
    }

    @OnClick(R.id.btn_two)
    public void screenPos(Button button){
        int[] location = new int[2];
        txt_pos.getLocationOnScreen(location);
        Log.d("dialog","window x is "  + Integer.toString(location[0]) + "y is " + Integer.toString(location[1]));
    }
}

运行,发现getLocationInWindow获得的值要比getLocationOnScreen的值要小,这就说明了getLocationInWindow获得的是在window里面窗口的坐标,getLocationOnScreen获得的是整个屏幕的绝对坐标。
接下来看看getLeft , getTop, getBottom, getRight这几个函数:
代码如下:

package com.example.jaime.viewpostest;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

//    @BindView(R.id.LocationInWindow) Button _btn_locationWindow;
//    @BindView(R.id.locationOnScreen) Button _btn_locationScreen;
    @BindView(R.id.textView) TextView _text_view;
    String tag = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.setDebug(BuildConfig.DEBUG);
        ButterKnife.bind(this);



    }


    @OnClick(R.id.gettop)
    public void gettop(Button button){
        int location = _text_view.getTop();
        Log.d(tag,"location x is " + Integer.toString(location));
        //初始化一个自定义的Dialog
        Dialog dialog = new MyDialog(this);
        dialog.show();
    }

    @OnClick(R.id.getbottom)
    public void getbottom(Button button){
        int location = _text_view.getBottom();
        Log.d(tag,"location x is " + Integer.toString(location));
    }

    @OnClick(R.id.getright)
    public void getright(Button button){
        int location = _text_view.getRight();
        Log.d(tag,"location x is " + Integer.toString(location));
    }

    @OnClick(R.id.getleft)
    public void getleft(Button button){
        int location = _text_view.getLeft();
        Log.d(tag,"location x is " + Integer.toString(location));
    }

    @OnClick(R.id.showDialog)
    public void showDialog(Button button){
        Dialog dialog = new MyDialog(this);
        dialog.show();
    }

}

XML文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.jaime.viewpostest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="Hello World!"
        android:layout_centerHorizontal="true"
        android:id="@+id/textView" />
    <!--<RelativeLayout-->
        <!--android:layout_width="wrap_content"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:layout_centerHorizontal="true"-->
        <!--android:layout_centerVertical="true">-->
        <!--<TextView-->
            <!--android:layout_width="wrap_content"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:layout_centerVertical="true"-->
            <!--android:text="Hello World!"-->
            <!--android:layout_centerHorizontal="true"-->
            <!--android:id="@+id/textView" />-->
    <!--</RelativeLayout>-->


    <Button
        android:id="@+id/gettop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="gettop"/>
    <Button
        android:id="@+id/getbottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getbottom"
        android:layout_below="@id/gettop"/>
    <Button
        android:id="@+id/getleft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getleft"
        android:layout_below="@id/getbottom"/>
    <Button
        android:id="@+id/getright"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getright"
        android:layout_below="@id/getleft"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/showDialog"
        android:text="windowandscreen"/>
</RelativeLayout>

打印为:
location x is 511
location x is 545
location x is 317
location x is 450
当改变xml文件如下时:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.jaime.viewpostest.MainActivity">

    <!--<TextView-->
        <!--android:layout_width="wrap_content"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:layout_centerVertical="true"-->
        <!--android:text="Hello World!"-->
        <!--android:layout_centerHorizontal="true"-->
        <!--android:id="@+id/textView" />-->
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="Hello World!"
            android:layout_centerHorizontal="true"
            android:id="@+id/textView" />
    </RelativeLayout>


    <Button
        android:id="@+id/gettop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="gettop"/>
    <Button
        android:id="@+id/getbottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getbottom"
        android:layout_below="@id/gettop"/>
    <Button
        android:id="@+id/getleft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getleft"
        android:layout_below="@id/getbottom"/>
    <Button
        android:id="@+id/getright"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="getright"
        android:layout_below="@id/getleft"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/showDialog"
        android:text="windowandscreen"/>
</RelativeLayout>

打印如下:
location x is 0
location x is 34
location x is 0
location x is 133
所以可以得出这几个函数得出的值都是相对于父节点所对应的坐标值
最后要做实验的几个函数是跟触摸有关的:
增加了一个activity来做实验,代码如下:

package com.example.jaime.viewpostest;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends Activity implements View.OnTouchListener{

//    @BindView(R.id.LocationInWindow) Button _btn_locationWindow;
//    @BindView(R.id.locationOnScreen) Button _btn_locationScreen;
//    @BindView(R.id.textView) TextView _text_view;
//    TextView _text_view;
    Button button;
    String tag = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    //    ButterKnife.setDebug(BuildConfig.DEBUG);
//        ButterKnife.bind(this);
        button = (Button)findViewById(R.id.gettop);
        button.setOnTouchListener(this);

    }


//    @OnClick(R.id.gettop)
//    public void gettop(Button button){
//        int location = _text_view.getTop();
//        Log.d(tag,"location x is " + Integer.toString(location));
//    }
//
//    @OnClick(R.id.getbottom)
//    public void getbottom(Button button){
//        int location = _text_view.getBottom();
//        Log.d(tag,"location x is " + Integer.toString(location));
//    }
//
//    @OnClick(R.id.getright)
//    public void getright(Button button){
//        int location = _text_view.getRight();
//        Log.d(tag,"location x is " + Integer.toString(location));
//    }
//
//    @OnClick(R.id.getleft)
//    public void getleft(Button button){
//        int location = _text_view.getLeft();
//        Log.d(tag,"location x is " + Integer.toString(location));
//    }
//
//    @OnClick(R.id.showDialog)
//    public void showDialog(Button button){
//        Dialog dialog = new MyDialog(this);
//        dialog.show();
//    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        int x  = 0;
        int y  = 0;
        int rawx = 0;
        int rawy = 0;
        int eventaction = motionEvent.getAction();
        switch (eventaction) {
            case MotionEvent.ACTION_DOWN:
                x = (int) motionEvent.getX();
                y = (int) motionEvent.getY();
                rawx = (int) motionEvent.getRawX();
                rawy = (int) motionEvent.getRawY();
                Log.d("DEBUG", "Down getX=" + x + "getY=" + y + "\n" + "getRawX=" + rawx
                        + "getRawY=" + rawy + "\n");
                break;
            case MotionEvent.ACTION_MOVE:
                x = (int) motionEvent.getX();
                y = (int) motionEvent.getY();
                rawx = (int) motionEvent.getRawX();
                rawy = (int) motionEvent.getRawY();
                Log.d("DEBUG", "getX=" + x + "getY=" + y + "\n" + "getRawX=" + rawx
                        + "getRawY=" + rawy + "\n");
                break;

            case MotionEvent.ACTION_UP:
                x = (int) motionEvent.getX();
                y = (int) motionEvent.getY();
                rawx = (int) motionEvent.getRawX();
                rawy = (int) motionEvent.getRawY();
                Log.d("DEBUG", "Up getX=" + x + "getY=" + y + "\n" + "getRawX=" + rawx
                        + "getRawY=" + rawy + "\n");
                break;
        }
        return false;
    }
}

打印如下:
Down getX=9getY=13
getRawX=37getRawY=590
结果表明getX,getY得到的是触摸点相对于增加点击事件的view的坐标,getRawX,getRawY得到的是相对于屏幕坐标的绝对坐标。今天睡不着,大晚上把这篇写完了,以后从源码的角度在分析一遍。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值