导航:首页 > 操作系统 > 安卓measure如何使用

安卓measure如何使用

发布时间:2022-09-27 03:25:27

android是怎样绘制视图的

当一个活动接收到焦点时,它将被要求绘制它的布局。Android框架将处理这个绘画的过程,但是活动必须提供它的布局层次的根节点。

绘画从布局的根节点开始。它被要求来测量和绘制布局树。绘画通过遍历布局树并渲染每个和失效区域相交的视图来处理。相应的,每个视图组负责请求绘制它的子视图(通过draw() 方法)而每个视图负责画它自己。因为这个树是顺序遍历的,这意味着先画父节点(也就是在屏幕后面),然后按照树中出现的顺序画其同层次节点。

框架将不会画不在失效区域的视图,而且还将会帮你画视图背景。

你可以强制一个视图被重画,通过调用invalidate()。

绘画布局共有两步:一个度量过程和一个布局过程。度量过程在measure(int, int)里实现且是一个自顶向下的视图树遍历。每个视图在递归时往下推送尺寸规格。在度量过程的最后,每个视图都已经保存了自己的度量。第二个过程发生在layout(int, int, int, int) 中并且也是自顶向下。在这个过程中,每个父节点负责定位它的所有子节点,通过使用在度量过程中计算得到的尺寸。

当一个视图的measure()方法返回时,它的getMeasuredWidth()和getMeasuredHeight() 值必须被设置,以及所有这个视图子节点的值。一个视图的度量的宽度和高度值必须符合父视图引入的限制。这确保在度量过程之后,所有父节点接受所有它们的子节点的度量值。一个父视图可能会在其子视图上多次调用measure()方法。比如,父视图可能会通过未指定的尺寸调用measure来发现它们的大小,然后使用实际数值再次调用measure(),如果所有子视图未做限制的尺寸总合过大或过小(也即是,如果子视图之间不能对各自占据的空间达成共识的话,父视图将会干预并设置第二个过程的规则)。

要开始一个布局,可调用requestLayout()。这个方法通常在视图认为它自己不再适合它当前的边界的情况下被调用。

度量过程使用两个类来交流尺寸。View.MeasureSpec类被视图用来告诉它们的父视图它们想如何被度量和定位。基础的LayoutParams类仅仅描述了视图想有多大(高和宽)。对于每个维度,它可以指定下面之一:

❷ Android 自定义View中onMeasure中使用resolveSize是什么意思

onmeasure方法主要是测量控件本身的大小(width,height)以及它的子控件的大小
不太明白你说的画布大小,但ondraw需要画的所有东西的大小,都要在onmeasure中测量获取

❸ Android:onmeasure()与measure()两方法有什么区 别

measure只有View类中才有这个方法,也就是说所有的View,像LinearLayout、Button这些控件的measure方法都是从View继承的,onMeasure方法才是真正的测量控件大小的方法,是由View的子类实现的,onMeasure是在measure方法中调用的

❹ Android问题:自定义视图的时候,onMeasure()这个方法有什么用

描述View本身大小的多少!

自定义View的时候重载onMeasure(),onLayout(),onDraw()三个函数构建了自定义View的外观形象。再加上onTouchEvent()等重载视图的行为,可以构建任何我们需要的可感知到的自定义View。

我们知道,不管是自定义View还是系统提供的TextView这些,它们都必须放置在LinearLayout等一些ViewGroup中,因此理论上我们可以很好的理解onMeasure(),onLayout(),onDraw()这三个函数:1.View本身大小多少,这由onMeasure()决定;2.View在ViewGroup中的位置如何,这由onLayout()决定;3.绘制View,onDraw()定义了如何绘制这个View。

❺ android手机布局,这个筛选布局该怎么样设置控件新手求大神讲解。。

ViewGroup在onLayout函数中通过调用其children的layout函数来设置子视图相对与父视图中的位置,具体位置由函数layout的参数决定,当我们继承ViewGroup时必须重载onLayout函数(ViewGroup中onLayout是abstract修饰),然而onMeasure并不要求必须重载,因为相对与layout来说,measure过程并不是必须的,具体后面会提到。首先我们来看下View.java中函数layout和onLayout的源码:public void layout(int l, int t, int r, int b) { int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; boolean changed = setFrame(l, t, r, b); if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) { if (ViewDebug.TRACE_HIERARCHY) { ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_LAYOUT); } onLayout(changed, l, t, r, b); mPrivateFlags &= ~LAYOUT_REQUIRED; ListenerInfo li = mListenerInfo; if (li != null && li.mOnLayoutChangeListeners != null) { ArrayList<OnLayoutChangeListener> listenersCopy = (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone(); int numListeners = listenersCopy.size(); for (int i = 0; i < numListeners; ++i) { listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB); } } } mPrivateFlags &= ~FORCE_LAYOUT; }函数layout的主体过程还是很容易理解的,首先通过调用setFrame函数来对4个成员变量(mLeft,mTop,mRight,mBottom)赋值,然后回调onLayout函数,最后回调所有注册过的listener的onLayoutChange函数。 对于View来说,onLayout只是一个空实现,一般情况下我们也不需要重载该函数:protected void onLayout(boolean changed, int left, int top, int right, int bottom) { }接着我们来看下ViewGroup.java中layout的源码:public final void layout(int l, int t, int r, int b) { if (mTransition == null || !mTransition.isChangingLayout()) { super.layout(l, t, r, b); } else { // record the fact that we noop'd it; request layout when transition finishes mLayoutSuppressed = true; } }super.layout(l, t, r, b)调用的即是View.java中的layout函数,相比之下ViewGroup增加了LayoutTransition的处理,LayoutTransition是用于处理ViewGroup增加和删除子视图的动画效果,也就是说如果当前ViewGroup未添加LayoutTransition动画,或者LayoutTransition动画此刻并未运行,那么调用super.layout(l, t, r, b),继而调用到ViewGroup中的onLayout,否则将mLayoutSuppressed设置为true,等待动画完成时再调用requestLayout()。 上面super.layout(l, t, r, b)会调用到ViewGroup.java中onLayout,其源码实现如下: @Override protected abstract void onLayout(boolean changed, int l, int t, int r, int b);和前面View.java中的onLayout实现相比,唯一的差别就是ViewGroup中多了关键字abstract的修饰,也就是说ViewGroup类只能用来被继承,无法实例化,并且其子类必须重载onLayout函数,而重载onLayout的目的就是安排其children在父视图的具体位置。重载onLayout通常做法就是起一个for循环调用每一个子视图的layout(l, t, r, b)函数,传入不同的参数l, t, r, b来确定每个子视图在父视图中的显示位置。 那layout(l, t, r, b)中的4个参数l, t, r, b如何来确定呢?联想到之前的measure过程,measure过程的最终结果就是确定了每个视图的mMeasuredWidth和mMeasuredHeight,这两个参数可以简单理解为视图期望在屏幕上显示的宽和高,而这两个参数为layout过程提供了一个很重要的依据(但不是必须的),为了说明这个过程,我们来看下LinearLayout的layout过程:void layoutVertical() { …… for (int i = 0; i < count; i++) { final View child = getVirtualChildAt(i); if (child == null) { childTop += measureNullChild(i); } else if (child.getVisibility() != GONE) { final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); …… setChildFrame(child, childLeft, childTop + getLocationOffset(child), childWidth, childHeight); childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child); i += getChildrenSkipCount(child, i); } } } private void setChildFrame(View child, int left, int top, int width, int height) { child.layout(left, top, left + width, top + height); }从setChildFrame可以看到LinearLayout中的子视图的右边界等于left + width,下边界等于top+height,也就是说在LinearLayout中其子视图显示的宽和高由measure过程来决定的,因此measure过程的意义就是为layout过程提供视图显示范围的参考值。 layout过程必须要依靠measure计算出来的mMeasuredWidth和mMeasuredHeight来决定视图的显示大小吗?事实并非如此,layout过程中的4个参数l, t, r, b完全可以由视图设计者任意指定,而最终视图的布局位置和大小完全由这4个参数决定,measure过程得到的mMeasuredWidth和mMeasuredHeight提供了视图大小的值,但我们完全可以不使用这两个值,可见measure过程并不是必须的。\\ 说到这里就不得不提getWidth()、getHeight()和getMeasuredWidth()、getMeasuredHeight()这两对函数之间的区别,getMeasuredWidth()、getMeasuredHeight()返回的是measure过程得到的mMeasuredWidth和mMeasuredHeight的值,而getWidth()和getHeight()返回的是mRight - mLeft和mBottom - mTop的值,看View.java中的源码便一清二楚了:public final int getMeasuredWidth() { return mMeasuredWidth & MEASURED_SIZE_MASK; } public final int getWidth() { return mRight - mLeft; }这也解释了为什么有些情况下getWidth()和getMeasuredWidth()以及getHeight()和getMeasuredHeight()会得到不同的值。

❻ android onmeasure什么时候调用

在开发中,当Android原生控件不能满足我们的需求的时候,就需要自定义View。View在屏幕上绘制出来先要经过measure(计算)和layout(布局)。
什么时候调用onMeasure方法?
当子View的父控件要放置该View的时候,父控件会传递两个参数给View——widthMeasureSpec和heightMeasureSpec。这两个参数是View可以获取的宽高尺寸和模式 混合的int数据。可以通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
mode共有三种情况,取 分别为
MeasureSpec.UNSPECIFIED,MeasureSpec.EXACTLY,MeasureSpec.AT_MOST。
MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数 时如
andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。
MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。
可以调用setMeasuredDimenson方法,将View的高度和宽度传入,设置子View实际的大小,告诉父控件需要多大的空间放置子View。
以下是框架中View的onMeasure的典型实现:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight, measuredWidth);
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that
// value.
result = specSize;
return result;
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that
// value.
result = specSize;
return result;
}

❼ 寻找一款可以在安卓手机里为照片标注尺寸的软件

Pico软件。

1、打开一张图片,双指放大图片,可以更精确地对标注进行调整,旋转角度、放大缩小。不满意的话点击右下角就能撤销操作,或者选中标注,点击删除。

❽ 安卓 自定义控件 什么时候要用到onmeasure方法

Android中View的绘制过程
当Activity获得焦点时,它将被要求绘制自己的布局,Android framework将会处理绘制过程,Activity只需提供它的布局的根节点。
绘制过程从布局的根节点开始,从根节点开始测量和绘制整个layout tree。
每一个ViewGroup 负责要求它的每一个孩子被绘制,每一个View负责绘制自己。
因为整个树是按顺序遍历的,所以父节点会先被绘制,而兄弟节点会按照它们在树中出现的顺序被绘制。

绘制是一个两遍(two pass)的过程:一个measure pass和一个layout pass。
测量过程(measuring pass)是在measure(int, int)中实现的,是从树的顶端由上到下进行的。
在这个递归过程中,每一个View会把自己的dimension specifications传递下去。
在measure pass的最后,每一个View都存储好了自己的measurements,即测量结果。

第二个是布局过程(layout pass),它发生在 layout(int, int, int, int)中,仍然是从上到下进行(top-down)。
在这一遍中,每一个parent都会负责用测量过程中得到的尺寸,把自己的所有孩子放在正确的地方。

阅读全文

与安卓measure如何使用相关的资料

热点内容
阿里程序员不加班离职 浏览:44
六级pdf 浏览:854
jsp嵌入java代码 浏览:161
Python中Windows字体颜色 浏览:692
n7笔记app哪个好 浏览:415
kindle用什么app好 浏览:719
方舟加密服务器怎么进 浏览:60
传文件夹太慢 浏览:218
基于单片机的仓库 浏览:377
央企直营朔源码燕窝 浏览:340
日本校园老师电影 浏览:65
买黄金首饰上什么app 浏览:452
共享pdf 浏览:343
老武侠电影,是一个女的用乳房打人,名字 浏览:649
pythonsocket库 浏览:401
缉魂130分钟台湾完整版 浏览:688
wifi电视一般需要什么app 浏览:526
怎样保护自己的id密码加密 浏览:244
韩剧女主手上带个铃铛 浏览:374
南充云服务器 浏览:984