从是否需要setLayoutParams说起
某天下午小喵正在全力完成最后一个需求,准备提测 突然有了点疑惑,在触摸事件中,按照以往动态改变某view的间距margin时,突然失去了效果,小喵是这么写的:
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)mTitleBar.getLayoutParams(); layoutParams.leftMargin = 10;
请教旁边几个大喵
大喵A说 : 我也是这么写的啊,没错啊,getLayoutParams()
大喵B说 : 错啦,少了个mTitleBar.setLayoutParams(layoutParams); 这时大佬瞄过来瞥了眼,幽幽的说了句:看下getLayoutParams和setLayoutParams两个方法源码吧 听大佬瞄这么一说,小喵翻出了源码:
@ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_") public ViewGroup.LayoutParams getLayoutParams() { return mLayoutParams; }
/** * Set the layout parameters associated with this view. These supply * parameters to the <i>parent</i> of this view specifying how it should be * arranged. There are many subclasses of ViewGroup.LayoutParams, and these * correspond to the different subclasses of ViewGroup that are responsible * for arranging their children. * * @param params The layout parameters for this view, cannot be null */ public void setLayoutParams(ViewGroup.LayoutParams params) { if (params == null) { throw new NullPointerException("Layout parameters cannot be null"); } mLayoutParams = params; resolveLayoutParams(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).onSetLayoutParams(this, params); } requestLayout(); }
setLayoutParams方法中多了个requestLayout(),小喵顿时明白了,在改变view的
layoutparams后,需要手动再setLayoutparams方法才行,这样view才会重新进行一次
重绘过程,小喵加上后的确立马起了效果。
但是小喵疑问来了,为啥以前没有发现呢,小喵翻了下以前的关于动态改变的代码,发现
的确没有手动调用setLayoutparams方法,但是最终也实现了效果。
小喵陷入了思考中,会不会和调用所在的方法有关呢,经过查找,发现之前都是在onCreate中执行的,而这次是在触摸事件中,也就是onCreate之后,难道是因为onCreate方法中view绘制还没完成,onResume中绘制才完成的原因?
经过翻看源码: 在调用了onCreate和onResume后,view还没有add到view中,即还没有绘制完成 performResumeActivity方法中发送handler消息回调onResume方法,但是在addview之前就已调用
总结,回到我们最初的问题
(1) 在onCreate和onResume设置参数,没有set同样有效,是因为此时view还没绘制完成,所以我们只需调用getLayoutparams拿到Layoutparams引用,接下来绘制完成就可起到效果。
(2) 而在view绘制完成之后,动态改变view时,必须手动调用setLayoutParams方法才行