写法
有时候咱们动态的设置一个view的height width 、margin的时候会经常写成:
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mTouchView.getLayoutParams();
layoutParams.width=111;
layoutParams.height=222;
你会发现即使不用 主动的 view.setLayoutParam()
,也能正确的生效,但是这种写法会存在一个潜在的问题,比如我如下写法的时候就会有问题:
mTouchView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRewardIcon.getViewTreeObserver().removeOnGlobalLayoutListener(this);
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) mTouchView.getLayoutParams();
layoutParams.topMargin = location[1] - DimenUtils.dip2px(4f);
}
});
上面的写法就会出问题,导致view不能正确的设置param,这个问题的真正原因是此时的mTouchView
已经layout完成,如果你动态的改变layoutParam
的属性,也就是只对变量赋值,但是view此时不会调用onLayout方法重新去layout,所以这个问题就会出现。
解法
手动调用 view.setLayoutParam() 方法。
分析
咱们看下 view.setLayoutParam()
里面都做了什么:
public void setLayoutParams(ViewGroup.LayoutParams params) {
if (params == null) {
throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;// 1.赋值
resolveLayoutParams();// 2.解析Param
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onSetLayoutParams(this, params);// 3、让父类知道这件事情
}
requestLayout();// 4.重新Layout
}
网友评论