In my open source library FloatingActioButton I need to programmatically change view margins specified by a user. Margins must be reduced by a shadow size (so that margin is set to the button itself and not to the shadow).
I override the onLayout
of the custom view class and use the following code:
@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;
}
}
}
But when I test it on the sample project I see that correct margins are applied only the first time on the first fragment (ListView). When I click on another tab, a new fragment is created (so complete layout is created) and the FAB is shifted (margins are not reduced by the shadow size):
Correct margins:
Wrong margins:
Even when I return to the first tab, the FAB stays with wrong margins. I tried to debug and saw that values calculated in onLayout
are the same in all cases. Margins calculated correctly.
Maybe onLayout
is not correct place to change margins?
I fixed it by moving a call to set margins to the onMeasure
method:
@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;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With