Android自定义控件坐标系解析

Android自定义控件坐标系解析,第1张

概述自定义控件要想彻底的把握,掌握Android各种坐标系及一些API的坐标含义毫无疑问是不可忽视的技能,对于控件的摆放位置、触摸点、控件绘制等都离不开坐标系,所以学习自定义控件之前我们就先来谈一下Android坐标系。一、Android屏幕坐标系和数学坐标系的区别(1)、在数学坐标系中

自定义控件要想彻底的把握,掌握AndroID各种坐标系及一些API的坐标含义毫无疑问是不可忽视的技能,对于控件的摆放位置、触摸点、控件绘制等都离不开坐标系,所以学习自定义控件之前我们就先来谈一下AndroID坐标系。

一、AndroID屏幕坐标系和数学坐标系的区别

(1)、在数学坐标系中以xy轴的交点为坐标原点,x轴向右为正方向,y轴向上为正方向,这对于童鞋们来说已经再熟悉不过了,如图:

(2)、而在手机屏幕上的坐标系与数学坐标系还是有差别的,移动设备一般定义屏幕左上角为坐标原点,x轴向右为正方向,y轴向下为正方向,如图:

二、AndroID屏幕区域的划分

AndroID屏幕区域主要划分为五个区域分别为:状态栏区域、Actionbar区域、VIEw布局区域、应用程序App区域、屏幕区域,相互之间又存在嵌套关系。如图所示:

下面我们来看看各个区域高度的获取:

(1)、状态栏区域高度获取:

        //第一种方式,使用此方法一定要等界面渲染结束        Rect rect = new Rect();        getwindow().getDecorVIEw().getwindowVisibledisplayFrame(rect);        int statusbarHeight = rect.top;                //第二种方式,获取状态栏高度        Resources resources = this.getResources();        int resourceID = resources.getIDentifIEr("status_bar_height", "dimen", "androID");        int height = resources.getDimensionPixelSize(resourceID);//此次获取状态栏高度          //第三种方式,通过反射方式获取状态栏高度        int statusHeight = -1;        try {            Class clazz = Class.forname("com.androID.internal.R$dimen");            Object object = clazz.newInstance();            int intheight = Integer.parseInt(clazz.getFIEld("status_bar_height")                    .get(object).toString());            //获取状态栏高度            statusHeight = this.getResources().getDimensionPixelSize(intheight);         } catch (Exception e) {            e.printstacktrace();        }

(2)、Actionbar区域高度获取:

        //第一种方式,此方法要等界面渲染结束        int actionbarHeight = getSupportActionbar().getHeight();        //第二种方式        TypedValue tv = new TypedValue();        if (this.gettheme().resolveAttribute(androID.R.attr.actionbarSize, tv, true)) {            int actionbarHeightOther = TypedValue.complexToDimensionPixelSize(                    tv.data, this.getResources().getdisplayMetrics());         }

(3)、VIEw布局区域高度获取:

  //第一种方式  Rect rect = new Rect();  getwindow().findVIEwByID(Window.ID_ANDROID_CONTENT).getDrawingRect(rect);  //第二种方式  //可见当执行onResume和onPause时,onWindowFocusChanged都会被调用。此时界面已渲染结束   @OverrIDe  public voID onWindowFocusChanged(boolean hasFocus) {    super.onWindowFocusChanged(hasFocus);    if (hasFocus) {        int wIDth = vIEw.getMeasureDWIDth();//获得宽度        int height = vIEw.getMeasuredHeight();//获得高度    }  }    //第三种方式  vIEw.post(new Runnable() {         @OverrIDe         public voID run() {             int wIDth=vIEw.getMeasureDWIDth();             int height=vIEw.getMeasuredHeight();         }     })       //第四种方式    vIEw.getVIEwTreeObserver().addOnGlobalLayoutListener(new VIEwTreeObserver.OnGlobalLayoutListener() {        @OverrIDe        public voID onGlobalLayout() {            vIEw.getVIEwTreeObserver().removeOnGlobalLayoutListener(this);            int wIDth=vIEw.getMeasureDWIDth();            int height=vIEw.getMeasuredHeight();        }    });

(4)、应用程序App区域高度获取:

 Rect rect = new Rect(); getwindow().getDecorVIEw().getwindowVisibledisplayFrame(rect);

(5)、屏幕区域高度获取:

        //第一种方式,该方式在4.1版本后已过时。        display display = getwindowManager().getDefaultdisplay();        int wIDth = display.getWIDth();        int height = display.getHeight();        //第二种方式        display defaultdisplay = getwindowManager().getDefaultdisplay();        Point point = new Point();        defaultdisplay.getSize(point);        int x = point.x;        int y = point.y;        //第三种方式        Rect outSize = new Rect();        getwindowManager().getDefaultdisplay().getRectSize(outSize);        int left = outSize.left;        int top = outSize.top;        int right = outSize.right;        int bottom = outSize.bottom;        //第四种方式        displayMetrics outMetrics = new displayMetrics();        getwindowManager().getDefaultdisplay().getMetrics(outMetrics);        int wIDthPixels = outMetrics.wIDthPixels;        int heightPixels = outMetrics.heightPixels;        //第五种方式        Point outSizeOther = new Point();        getwindowManager().getDefaultdisplay().getRealSize(outSizeOther);        int x1 = outSizeOther.x;        int y1 = outSizeOther.y;        //第六种方式        displayMetrics outMetrics1 = new displayMetrics();        getwindowManager().getDefaultdisplay().getRealMetrics(outMetrics1);        int wIDthPixel = outMetrics1.wIDthPixels;        int heightPixel = outMetrics1.heightPixels;

特别注意:上面这些方法最好在Activity的onWindowFocusChanged()方法或者之后调用,因为只有这时候才是真正的显示完全。

三、AndroID坐标系的分类

上面我们分析了AndroID屏幕区域的划分,接着我们分析一下与区域相关的AndroID坐标系,在AndroID坐标系中可以分为:屏幕坐标系,视图坐标系。

(1)、屏幕坐标系

屏幕坐标系我们前面在和数学坐标系的区别已经介绍过了,以屏幕左上角为坐标原点,x轴向右为正方向,y轴向下为正方向,如图所示:

(2)、视图坐标系

视图坐标系在VIEw绘制过程中,绘制的内容将以坐标系作为参考,最后确定绘制内容在VIEw里面的位置。

下面我们来看看常用的坐标方法,注意这些方法是相对父容器而言的:

VIEw相关方法 : 方法说明

vIEw.getleft(): 当前VIEw的左边缘与它父VIEw的左边缘的距离(视图坐标);

vIEw.getRight(): 当前VIEw的右边缘与它父VIEw的左边缘的距离(视图坐标);

vIEw.gettop(): 当前VIEw的上边缘与它父VIEw的上边缘(顶部)的距离(视图坐标);

vIEw.getBottom(): 当前VIEw的下边缘与它父VIEw的上边缘(顶部)的距离(视图坐标);

VIEw.getTranslationX(): 当前VIEw在X轴的偏移量。初始值为0,向左偏移值为负,向右偏移值为正;(常见于属性动画中)

VIEw.getTranslationY(): 当前VIEw在Y轴的偏移量。初始值为0,向上偏移为负,向下偏移为正;(常见于属性动画中)

VIEw.getX: 当前VIEw在X轴的偏移量。初始值为0,向左偏移值为负,向右偏移值为正;返回值为getleft()+getTranslationX(),当setTranslationX()变getleft()不变时,getX()变。

VIEw.getY: 当前VIEw在Y轴的偏移量。初始值为0,向上偏移为负,向下偏移为正;返回值为gettop()+getTranslationY(),当setTranslationY()变gettop()不变时,getY()变。

为了解释清楚这些方法,准备了张图,如图所示:

此时我们可以获取视图(VIEw)宽高的方法:

VIEw宽高方法 : 方法说明
getWIDth(): 当前VIEw的宽度,即getRight()-getleft()
getHeight(): 当前VIEw宽度,即getBottom()-gettop()

需要注意的是使用以上方法的过程中要在VIEw测量结束即渲染完成后,不然获取到的值为0。

我们再来看看手指触摸屏幕时MotionEvent提供的一些方法解释:

MotionEvent坐标方法: 方法说明
getX(): 触摸中心点与该VIEw左边缘的距离(相对坐标)
getY(): 触摸中心点与该VIEw上边缘的距离(相对坐标)
getRawX(): 触摸中心点与屏幕左边缘的距离(绝对坐标)
getRawY(): 触摸中心点与屏幕上边缘的距离(绝对坐标)

为了解释清楚这些方法,准备了张图,如图所示:

今天的内容就到这啦,本文主要就是阐述VIEw里常用方法及坐标相关的概念,也是为后期的内容做铺垫。欢迎关注公众号【龙旋】能获取最新更新内容哦。

总结

以上是内存溢出为你收集整理的Android自定义控件坐标系解析全部内容,希望文章能够帮你解决Android自定义控件坐标系解析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1005112.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存