自定义控件要想彻底的把握,掌握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自定义控件坐标系解析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)