高效包裹解决方案:提升包装效率的实用技巧

更新:10-28 民间故事 我要投稿 纠错 投诉

大家好,今天给各位分享高效包裹解决方案:提升包装效率的实用技巧的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

wrapp_content/match_parent可以让view的宽高灵活变化的秘诀是什么?

measureSpec影响宽高的计算

视图的绘制过程主要由三个部分组成:测量、布局、绘制。测量过程就是计算View的宽度和高度的过程,主要是通过onMeasure方法实现的。

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

.

}onMeasure方法从父视图接收子视图宽度和高度的measureSpec约束。具体视图会根据measureSpec计算视图的宽度和高度。

measureSpec的一些概念:measureSpec是一个32位值。前两位表示测量模式,后30位表示测量大小。

共有三种测量模式:

确切地说:父控件确定子控件的特定大小。

AT_MOST:子控件最多达到指定的大小值。

UNSPECIFIED:父控件不对子控件施加任何约束,子控件可以获得任何想要的大小。

android提供了相应的方法来处理measureSpec

//获取测量模式

int specMode=MeasureSpec.getMode(measureSpec);

//获取测量的尺寸

int specSize=MeasureSpec.getSize(measureSpec);

//根据尺寸和模式生成measureSpec

MeasureSpec.makeMeasureSpec(resultSize, resultMode);例如 TextView的onMeasure实现://onMeasure关键实现

@覆盖

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthMode=MeasureSpec.getMode(widthMeasureSpec);

int heightMode=MeasureSpec.getMode(heightMeasureSpec);

int widthSize=MeasureSpec.getSize(widthMeasureSpec);

int heightSize=MeasureSpec.getSize(heightMeasureSpec);

if (widthMode==MeasureSpec.EXACTLY) {

//父母已经告诉我们要多大。就这样吧。

宽度=宽度尺寸;

} 别的{

.

if (widthMode==MeasureSpec.AT_MOST) {

宽度=Math.min(widthSize, 宽度);

}

}

.

if (heightMode==MeasureSpec.EXACTLY) {

//父母已经告诉我们要多大。就这样吧。

高度=高度尺寸;

mDesiredHeightAtMeasure=-1;

} 别的{

.

if (heightMode==MeasureSpec.AT_MOST) {

高度=Math.min(期望值, heightSize);

}

}

.

setMeasuredDimension(宽度,高度);

}第一的:

从父视图的约束measureSpec 获取约束的模式specMode 和约束的大小specSize。

第二:

如果mode为EXACTLY(父控件决定子控件的具体尺寸),则TextView的宽高直接是父View约束的宽高;

如果模式为AT_MOST(子控件最多达到指定大小),则取TextView自身大小和父视图约束大小的最小值;

如果是UNSPECIFIED(父控件不对子控件施加任何约束,子控件可以获得任何想要的大小),TextView将采用TextView本身的大小,无需额外处理。

因此,视图的宽度和高度的计算是由父视图传递的约束measureSpec决定的。

那么measureSpec从哪里来呢?

wrap_content/match_parent影响measureSpec的计算

父视图在自己测量时会调用子视图的onMeasure方法,测量子视图例如,以下布局:

?xml version="1.0"encoding="utf-8"?实测时序图:

image.png在measureChildWithMargins方法中调用子视图的measure方法,最终执行子视图的onMeasure方法。

protected voidmeasureChildWithMargins(View child, int ParentWidthMeasureSpec, int widthUsed,

intparentHeightMeasureSpec, int heightUsed) {

最终MarginLayoutParams lp=(MarginLayoutParams) child.getLayoutParams();

最终int childWidthMeasureSpec=getChildMeasureSpec(parentWidthMeasureSpec,

mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin + widthUsed, lp.width);

最终int childHeightMeasureSpec=getChildMeasureSpec(parentHeightMeasureSpec,

mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin + heightUsed, lp.height);

child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

}子视图onMeasure方法所需的measureSpec是通过getChildMeasureSpec方法获取的。

公共静态int getChildMeasureSpec(int 规范, int 填充, int childDimension) {

int specMode=MeasureSpec.getMode(spec);

int specSize=MeasureSpec.getSize(spec);

int size=Math.max(0, specSize - 填充);

int 结果大小=0;

int 结果模式=0;

开关(规格模式){

//父级给我们强加了一个精确的尺寸

案例MeasureSpec.EXACTLY:

if (子维度=0) {

结果大小=子维度;

resultMode=MeasureSpec.EXACTLY;

} else if (childDimension==LayoutParams.MATCH_PARENT) {

//孩子想要成为我们的尺寸。就这样吧。

结果大小=大小;

resultMode=MeasureSpec.EXACTLY;

} else if (childDimension==LayoutParams.WRAP_CONTENT) {

//孩子想要确定自己的大小。不可能是

//比我们大。

结果大小=大小;

resultMode=MeasureSpec.AT_MOST;

}

休息;

//父级给我们施加了最大尺寸

案例MeasureSpec.AT_MOST:

if (子维度=0) {

//孩子想要一个特定的尺寸.就这样吧

结果大小=子维度;

resultMode=MeasureSpec.EXACTLY;

} else if (childDimension==LayoutParams.MATCH_PARENT) {

//孩子想要成为我们的尺寸,但我们的尺寸不固定。

//限制孩子不比我们大。

结果大小=大小;

resultMode=MeasureSpec.AT_MOST;

} else if (childDimension==LayoutParams.WRAP_CONTENT) {

//孩子想要确定自己的大小。不可能是

//比我们大。

结果大小=大小;

resultMode=MeasureSpec.AT_MOST;

}

休息;

//家长要求看看我们想要多大

案例MeasureSpec.UNSPECIFIED:

if (子维度=0) {

//孩子想要特定的尺寸.让他拥有

结果大小=子维度;

resultMode=MeasureSpec.EXACTLY;

} else if (childDimension==LayoutParams.MATCH_PARENT) {

//孩子想要成为我们的尺寸.找出它应该有多大

//是

resultSize=View.sUseZeroUnspecifiedMeasureSpec ? 0 : 大小;

resultMode=MeasureSpec.UNSPECIFIED;

} else if (childDimension==LayoutParams.WRAP_CONTENT) {

//孩子想要确定自己的大小.了解如何

//应该很大

resultSize=View.sUseZeroUnspecifiedMeasureSpec ? 0 : 大小;

resultMode=MeasureSpec.UNSPECIFIED;

}

休息;

}

//无检查资源类型

返回MeasureSpec.makeMeasureSpec(resultSize, resultMode);在getChildMeasureSpec方法中,终于看到了久违的wrap_contentmatch_parent。可以看到,子视图的measureSpec是由两部分决定的,父视图的measureSpec和子视图的LayoutParams。

如果子视图的LayoutParams宽度和高度设置为特定尺寸

.

if (子维度=0) {

结果大小=子维度;

resultMode=MeasureSpec.EXACTLY;

}

.则子视图measurerSpec约束模式为EXACTLY,约束尺寸为LayoutParams中定义的尺寸。根据前面介绍的TextView的onMeasure方法逻辑,计算出来的尺寸就是约束尺寸。

如果父视图约束模式为EXACTLY(通常将父视图的宽度和高度定义为具体尺寸),则子视图LayoutParams定义为match_parent(以填充父视图)

.

案例MeasureSpec.EXACTLY:

if (childDimension==LayoutParams.MATCH_PARENT) {

//孩子想要成为我们的尺寸。就这样吧。

结果大小=大小;

resultMode=MeasureSpec.EXACTLY;

}

.获取到的子视图的measureSpec约束方式仍然是EXACTLY,约束尺寸为父视图约束的尺寸,并且TextView计算出的宽高与父视图一样大,达到填充父视图的效果看法;

如果子视图定义为wrap_content

.

案例MeasureSpec.EXACTLY:

if (childDimension==LayoutParams.WRAP_CONTENT) {

//孩子想要确定自己的大小。不可能是

//比我们大。

结果大小=大小;

resultMode=MeasureSpec.AT_MOST;

}

.获取到的子视图的measureSpec约束模式为AT_MOST,约束大小为父视图约束的大小。 TextView计算出的宽度和高度与父视图的最小约束尺寸相同。宽度和高度由其自身尺寸决定。但不会超出父视图的约束大小。

其他的组合方法还有很多,我就不一一列举了。可以看到我们平时记忆和理解的wrap_contentmatch_parent灵活改变view的宽高的效果主要就是通过这段代码逻辑来实现的。

理解视图测量时的一些疑问:

顶层视图的measureSpec的由来

从前面的讨论可以知道,测量方法的参数measureSpec是从父视图传入的,那么顶层视图的measureSpec从哪里来呢?

我们经常给activity设置的layout布局的根视图并不是顶层视图。

我们先看一张图:

image.pngcontent 部分是为Activity 设置的布局。外层还有一个视图DecorView。这是顶层视图。

DecorView的测量过程在ViewRootImpl的performTraversals方法中。

私人无效performTraversals(){

.

//获取视图宽度和高度的测量规格,mWidth和mHeight代表窗口的宽度和高度,lp.widthhe和lp.height代表DecorView根布局的宽度和高度

int childWidthMeasureSpec=getRootMeasureSpec(mWidth, lp.width);

int childHeightMeasureSpec=getRootMeasureSpec(mHeight, lp.height);

//询问主机想要多大

//执行测量操作

执行测量(childWidthMeasureSpec,childHeightMeasureSpec);

.

//执行布局操作

执行布局(lp,desiredWindowWidth,desiredWindowHeight);

.

//执行绘图操作

执行绘图();

.

}DecorView的测量规范是通过getRootMeasureSpec方法创建的,DecorView的测量是在performMeasure方法中执行的,遍历整个子视图。

而视图的布局和绘制也是从这里开始的。通过依次执行performMeasure、performLayout、performDraw方法,完成整个页面绘制过程。

ListView对子视图测量的区别

ListView的子视图布局高度无论设置为wrap_content还是match_parent,其高度都是子视图本身的大小。这是为什么呢?

ListView中子视图的测量调用了自己定义的方法measureScrapChild。

私有无效measureScrapChild(查看孩子,int位置,int widthMeasureSpec,int heightHint){

LayoutParams p=(LayoutParams) child.getLayoutParams();

.

if (lpHeight 0) {

childHeightSpec=MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);

} 别的{

childHeightSpec=MeasureSpec.makeSafeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED);

}

child.measure(childWidthSpec, childHeightSpec);

关于高效包裹解决方案:提升包装效率的实用技巧和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

用户评论

ヅ她的身影若隐若现

包装纸真方便,能保护东西不被弄脏

    有9位网友表示赞同!

有些人,只适合好奇~

学习一些漂亮的包装技巧,礼物瞬间提升档次

    有17位网友表示赞同!

雁過藍天

包裹着美味的食物,更添了一份期待感

    有10位网友表示赞同!

〆mè村姑

不知道为啥特别喜欢用布包裹小物件,很居家哦~

    有14位网友表示赞同!

青瓷清茶倾城歌

包装纸还可以DIY做装饰品,挺酷的

    有13位网友表示赞同!

烟雨离殇

礼物收到之后最好是包装精美些,看着就开心!

    有12位网友表示赞同!

孤败

我超讨厌去商店买东西时,包装袋总是那么薄)

    有12位网友表示赞同!

不忘初心

如果包装太过于复杂的话会感觉很麻烦呀!

    有18位网友表示赞同!

青衫故人

希望环保包装能够更普及一点~

    有17位网友表示赞同!

为爱放弃

现在很多店用纸盒包装很好看,很有设计感

    有13位网友表示赞同!

冷月花魂

我很喜欢自己动手包装礼物的感觉很满足!

    有11位网友表示赞同!

无寒

包装纸的颜色很重要啊,看着舒服才能心情好

    有13位网友表示赞同!

长裙绿衣

包裹东西的时候可以准备一些亮片或带装饰性的绳子

    有7位网友表示赞同!

温柔腔

想学习怎么做那种精美的盒子包装

    有9位网友表示赞同!

秘密

有时候收到包裹时,特别喜欢拆开包裹的过程

    有13位网友表示赞同!

孤者何惧

如果不小心把东西弄坏了,包装纸就显得很有用了

    有12位网友表示赞同!

留我一人

包装纸的选择和材质也很重要吧!

    有20位网友表示赞同!

该用户已上天

有些物品不适合用普通的包装纸包饰哦

    有17位网友表示赞同!

别伤我i

包装其实也可以体现一个人的审美

    有7位网友表示赞同!

【高效包裹解决方案:提升包装效率的实用技巧】相关文章:

1.动物故事精选:寓教于乐的儿童故事宝库

2.《寓教于乐:精选动物故事助力儿童成长》

3.探索动物旅行的奇幻冒险:专为儿童打造的童话故事

4.《趣味动物刷牙小故事》

5.探索坚韧之旅:小蜗牛的勇敢冒险

6.传统风味烤小猪,美食探索之旅

7.探索奇幻故事:大熊的精彩篇章

8.狮子与猫咪的奇妙邂逅:一场跨界的友谊故事

9.揭秘情感的力量:如何影响我们的生活与决策

10.跨越两岸:探索彼此的独特世界

上一篇:壹葵星系每日运势解读 | 11月2日运势分析 下一篇:深情相拥:为世间真挚的爱情献上祝福