在我的开源库FloatingActioButton中,我需要以编程方式更改用户指定的视图边距。边距必须减少阴影大小(因此边距设置为按钮本身而不是阴影)。
我覆盖自定义视图类的onLayout
并使用以下代码:
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!hasLollipopApi() && !mMarginsSet) {
if (getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
int leftMargin = lp.leftMargin - mShadowSize;
int topMargin = lp.topMargin - mShadowSize;
int rightMargin = lp.rightMargin - mShadowSize;
int bottomMargin = lp.bottomMargin - mShadowSize;
lp.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
setLayoutParams(lp);
mMarginsSet = true;
}
}
}
但是当我在示例项目上测试它时,我发现只有第一次在第一个片段(ListView)上应用了正确的边距。当我单击另一个选项卡时,会创建一个新片段(因此创建完整的布局)并且FAB会移位(边距不会减少阴影大小):
更正边距:
错误的保证金:
即使我返回第一个标签页,FAB也会保留错误的边距。我尝试调试并发现在onLayout
中计算的值在所有情况下都是相同的。边距计算正确。
可能onLayout
不是改变边距的正确位置?
答案 0 :(得分:13)
我通过调用将边距设置为onMeasure
方法来修复它:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = getDimension(
mType == TYPE_NORMAL ? R.dimen.fab_size_normal : R.dimen.fab_size_mini);
if (mShadow && !hasLollipopApi()) {
size += mShadowSize * 2;
setMarginsWithoutShadow();
}
setMeasuredDimension(size, size);
}
private void setMarginsWithoutShadow() {
if (!mMarginsSet) {
if (getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
int leftMargin = layoutParams.leftMargin - mShadowSize;
int topMargin = layoutParams.topMargin - mShadowSize;
int rightMargin = layoutParams.rightMargin - mShadowSize;
int bottomMargin = layoutParams.bottomMargin - mShadowSize;
layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
requestLayout();
mMarginsSet = true;
}
}
}