在Android中,如何以编程方式在dp中设置边距?

问题描述 投票:345回答:16

thisthisthis帖子中,我试图找到关于如何在单个视图上设置边距的答案。但是,我想知道是否有更简单的方法。我会解释为什么我宁愿不想使用这种方法:

我有一个自定义Button,扩展了Button。如果背景设置为默认背景以外的其他东西(通过调用setBackgroundResource(int id)setBackgroundDrawable(Drawable d)),我希望边距为0.如果我这样称呼:

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

我希望边距重置为-3dp(我已经读过here如何从像素转换为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();returns ViewGroup.LayoutParams,没有属性topMarginbottomMarginleftMarginrightMargin。您看到的mc实例只是一个MarginContainer,它包含偏移(-3dp)边距和(oml,omr,omt,omb)和原始边距(ml,mr,mt,mb)。

android layout button margin
16个回答
700
投票

您应该使用LayoutParams设置按钮边距:

LayoutParams params = new LayoutParams(
        LayoutParams.WRAP_CONTENT,      
        LayoutParams.WRAP_CONTENT
);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);

根据您使用的布局,您应该使用RelativeLayout.LayoutParamsLinearLayout.LayoutParams

要将dp度量转换为像素,请尝试以下操作:

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);

1
投票

用于快速单线设置使用

((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);

但要小心对LayoutParams的任何错误使用,因为这将没有qazxsw poi语句实例chech


0
投票

就像今天一样,最好的可能是使用由AirBnB提供的if库。

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

Paris

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

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

0
投票
@Styleable and @Style

我不得不把它扔给((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250); linearLayout.setBackgroundResource(R.drawable.smartlight_background); 一个linearLayout,因为它继承了它并在那里设置了边距,所以活动只出现在屏幕的一部分上,并且背景与FrameLayout中的原始布局参数不同。

setContentView

其他人都没有使用相同的活动,并根据从不同菜单打开活动来更改边距! setLayoutParams对我来说从未起作用 - 设备每次都会崩溃。即使这些是硬编码的数字 - 这仅仅是用于演示目的的代码示例。


0
投票

为那些可能觉得方便的人创建了Kotlin扩展功能。

确保传入的像素不是dp。快乐编码:)

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
linearLayout.setBackgroundColor(getResources().getColor(R.color.full_white));
setContentView(linearLayout,layoutParams);

0
投票

在我的例子中,我以编程方式将ImageView添加到LinearLayout。我已将顶部和底部边距设置为ImagerView。然后将ImageView添加到LinearLayout。

fun View.addLayoutMargins(left: Int? = null, top: Int? = null,
                      right: Int? = null, bottom: Int? = null) {
    this.layoutParams = ViewGroup.MarginLayoutParams(this.layoutParams)
            .apply {
                left?.let { leftMargin = it }
                top?.let { topMargin = it }
                right?.let { rightMargin = it }
                bottom?.let { bottomMargin = it }
            }
}

0
投票

您可以使用此方法并根据您的设备将静态维数(如20)转换为它



        ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmap);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        params.setMargins(0, 20, 0, 40);
        imageView.setLayoutParams(params);
        linearLayout.addView(imageView);


0
投票

更新:

就像你曾经使用 public static int dpToPx(int dp) { float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } 设置布局宽度和高度一样

你可以使用ViewGroup.LayoutParams来设置宽度,高度和边距,非常自我解释吧?

ViewGroup.MarginLayoutParams

方法ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); marginLayoutParams.setMargins(0,16,0,16); linearLayout.setLayoutParams(marginLayoutParams); 分别采用left,top,right,bottom的值。顺时针!,从左边开始。


192
投票

LayoutParams - 不工作! ! !

需要使用的类型:MarginLayoutParams

MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;

MarginLayoutParams的代码示例:

http://www.codota.com/android/classes/android.view.ViewGroup.MarginLayoutParams


99
投票

最好的方式:

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);

希望这会帮助你。


29
投票
int sizeInDP = 16;

int marginInDp = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, sizeInDP, getResources()
                    .getDisplayMetrics());

然后

layoutParams = myView.getLayoutParams()
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

要么

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

9
投票

Here is the all-in-one answer with recent updates:

第1步,更新保证金

基本的想法是获得保证金,然后更新它。更新将自动应用,您无需将其重新设置。要获取布局参数,只需调用此方法:

LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();

LayoutParams来自您的视图布局。如果视图来自线性布局,则需要导入LinearLayout.LayoutParams。如果使用相对布局,请导入LinearLayout.LayoutParams等。

现在,如果你使用Layout_marginLeftRight等设置保证金,你需要以这种方式更新保证金

layoutParams.setMargins(left, top, right, bottom);

如果使用新的layout_marginStart设置保证金,则需要以这种方式更新保证金

layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);

步骤2,更新dp中的保证金

更新上述边距的所有两种方式都是以像素更新。您需要将dp转换为像素。

float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;

现在将计算值放到上面的边际更新函数中,您应该全部设置


7
投票

layout_margin是视图子项告诉其父级的约束。然而,父母的角色是选择是否允许保证金。基本上通过设置android:layout_margin =“10dp”,孩子正在恳求父视图组分配比实际大小大10dp的空间。 (padding =“10dp”,另一方面,意味着子视图将使其自己的内容缩小10dp。)

因此,并非所有ViewGroup都尊重保证金。最臭名昭着的例子是listview,其中项目的边距被忽略。在将setMargin()调用LayoutParam之前,应始终确保当前视图位于支持边距的ViewGroup(例如LinearLayouot或RelativeLayout)中,并将getLayoutParams()的结果强制转换为所需的特定LayoutParams。 (ViewGroup.LayoutParams甚至没有setMargins()方法!)

下面的功能应该可以解决问题。但是,请确保将RelativeLayout替换为父视图的类型。

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}

7
投票

此方法可让您在DP中设置保证金

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);
}

UPDATE

您可以更改适合您需要的参数。


2
投票

当你在自定义视图中,你可以使用getDimensionPixelSize(R.dimen.dimen_value),在我的情况下,我在init方法上创建的LayoutParams中添加了边距。

在科特林

init {
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true)
    layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
    val margin = resources.getDimensionPixelSize(R.dimen.dimen_value)
    setMargins(0, margin, 0, margin)
}

在Java中:

public class CustomView extends LinearLayout {

    //..other constructors

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.spacing_dime);
        params.setMargins(0, margin, 0, margin);
        setLayoutParams(params);
    }
}

1
投票

使用此方法在dp中设置边距

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();

        final float scale = getBaseContext().getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int l =  (int)(left * scale + 0.5f);
        int r =  (int)(right * scale + 0.5f);
        int t =  (int)(top * scale + 0.5f);
        int b =  (int)(bottom * scale + 0.5f);

        p.setMargins(l, t, r, b);
        view.requestLayout();
    }
}

调用方法:

setMargins(linearLayout,5,0,5,0);
© www.soinside.com 2019 - 2024. All rights reserved.