在这个,这个和这个线程中,我试图找到一个关于如何在单个视图上设置边缘的答案。然而,我想知道是否有更简单的方法。我将解释为什么我不想使用这种方法:

我有一个自定义按钮扩展按钮。如果背景被设置为默认背景以外的东西(通过调用setBackgroundResource(int id)或setBackgroundDrawable(Drawable d)),我希望边缘为0。如果我调用这个:

public void setBackgroundToDefault() {
    backgroundIsDefault = true;
    super.setBackgroundResource(android.R.drawable.btn_default);
    // Set margins somehow
}

我希望边距重置为-3dp(我已经在这里读到如何从像素转换为dp,所以一旦我知道如何设置px边距,我可以自己管理转换)。但是由于这是在CustomButton类中调用的,父类可以从LinearLayout到TableLayout变化,我宁愿不让他获得他的父类并检查该父类的实例。我想那也不太合适。

另外,当调用(使用LayoutParams) parentLayout。addView(myCustomButton, newParams),我不知道这是否将它添加到正确的位置(但是还没有尝试过),说一行中的五个按钮。

问:除了使用LayoutParams,还有什么更简单的方法来编程设置单个按钮的边距吗?

编辑:我知道的LayoutParams方式,但我想要一个解决方案,避免处理每个不同的容器类型:

ViewGroup.LayoutParams p = this.getLayoutParams();
    if (p instanceof LinearLayout.LayoutParams) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof RelativeLayout.LayoutParams) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof TableRow.LayoutParams) {
        TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
}

因为this.getLayoutParams();返回一个ViewGroup。LayoutParams,它们没有属性topMargin, bottomMargin, leftMargin, rightMargin。 你看到的mc实例只是一个MarginContainer,它包含偏移量(-3dp)边距和(oml, omr, omt, omb)和原始边距(ml, mr, mt, mb)。


当前回答

这个方法可以让你在DP中设置Margin

public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {

        final float scale = con.getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int pixel =  (int)(dp * scale + 0.5f); 

        ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
        s.setMargins(pixel,pixel,pixel,pixel);

        yourView.setLayoutParams(params);
}

更新

您可以根据需要更改参数。

其他回答

感兴趣的人可以使用DP工作utils函数:

public static void setMargins(Context context, View view, int left, int top, int right, int bottom) {
    int marginLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, left, context.getResources().getDisplayMetrics());
    int marginTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, top, context.getResources().getDisplayMetrics());
    int marginRight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, right, context.getResources().getDisplayMetrics());
    int marginBottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, bottom, context.getResources().getDisplayMetrics());

    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(marginLeft, marginTop, marginRight, marginBottom);
        view.requestLayout();
    }
}

@Lyusten Elder的答案是正确的,但不要忘记,在这样做之前,你需要将px转换为dp。

是这样的:

public static int getDpFromPx(Context context, float px) {
    return Math.round(px * context.getResources().getDisplayMetrics().density);
}

最好的方式:

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(left, top, right, bottom);
        view.requestLayout();
    }
}

如何调用方法:

setMargins(mImageView, 50, 50, 50, 50);

希望这对你有所帮助。

val params = FrameLayout.LayoutParams(
    ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.MATCH_PARENT
)
params.setMargins(0, 0, 0, 400)
binding.container.setLayoutParams(params)

就像今天一样,最好的办法可能是使用AirBnB提供的巴黎图书馆。

然后可以像这样应用样式:

Paris.style(myView).apply(R.style.MyStyle);

它还支持使用注释的自定义视图(如果你扩展了一个视图):

@Styleable and @Style