更改自定义视图内部的边距

7
在我的开源库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会被移动(边距不会减少阴影大小):
正确的边距: Correct margins 错误的边距: Wrong margins 即使我返回到第一个选项卡,FAB的边距也保持不变。我尝试调试并看到在所有情况下都在onLayout中计算的值相同。边距被正确计算。
也许onLayout不是改变边距的正确位置?
1个回答

16

我通过将设置边距的调用移动到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;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接