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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12728255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:36:03  来源:igfitidea点击:

In Android, how do I set margins in dp programmatically?

androidlayoutbuttonmargin

提问by stealthjong

In this, thisand thisthread I tried to find an answer on how to set the margins on a single view. However, I was wondering if there isn't an easier way. I'll explain why I rather wouldn't want to use this approach:

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

I have a custom Button which extends Button. If the background is set to something else than the default background (by calling either setBackgroundResource(int id)or setBackgroundDrawable(Drawable d)), I want the margins to be 0. If I call this:

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

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

I want the margins to reset to -3dp (I already read herehow to convert from pixels to dp, so once I know how to set margins in px, I can manage the conversion myself). But since this is called in the CustomButtonclass, the parent can vary from LinearLayout to TableLayout, and I'd rather not have him get his parent and check the instanceof that parent. That'll also be quite inperformant, I imagine.

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

Also, when calling (using LayoutParams) parentLayout.addView(myCustomButton, newParams), I don't know if this adds it to the correct position (haven't tried however), say the middle button of a row of five.

此外,在调用 (使用 LayoutParams) 时parentLayout.addView(myCustomButton, newParams),我不知道这是否将其添加到正确的位置(但是还没有尝试过),比如五行的中间按钮。

Question: Is there any easier way to set the margin of a single Button programmatically besides using LayoutParams?

问题:除了使用 LayoutParams 之外,还有没有更简单的方法来以编程方式设置单个 Button 的边距

EDIT: I know of the LayoutParams way, but I'd like a solution that avoids handling each different container type:

编辑:我知道 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);
    }
}

Because this.getLayoutParams();returns a ViewGroup.LayoutParams, which do not have the attributes topMargin, bottomMargin, leftMargin, rightMargin. The mc instance you see is just a MarginContainerwhich contains offset (-3dp) margins and (oml, omr, omt, omb) and the original margins (ml, mr, mt, mb).

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

回答by throrin19

You should use LayoutParamsto set your button margins:

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

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

Depending on what layout you're using you should use RelativeLayout.LayoutParamsor LinearLayout.LayoutParams.

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

And to convert your dp measure to pixel, try this:

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

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

回答by Lyusten Elder

LayoutParams - NOT WORKING ! ! !

LayoutParams - 不工作!!!

Need use type of: MarginLayoutParams

需要使用类型:MarginLayoutParams

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

Code Example for MarginLayoutParams:

MarginLayoutParams 的代码示例:

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

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

回答by Hiren Patel

Best way ever:

有史以来最好的方法:

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

How to call method:

如何调用方法:

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

Hope this will help you.

希望这会帮助你。

回答by sagits

int sizeInDP = 16;

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

Then

然后

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

Or

或者

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

回答by Fangming

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

这是最近更新的多合一答案:

Step 1, to update margin

第 1 步,更新保证金

The basic idea is to get margin out and then update it. The update will be applies automatically and you do not need to set it back. To get the layout parameters, simply call this method:

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

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

The LayoutParamscomes from the layout of your view. If the view is from a linear layout, you need to import LinearLayout.LayoutParams. If you use relative layout, import LinearLayout.LayoutParams, etc.

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

Now, if you set the margin using Layout_marginLeft, Right, etc, you need to update margin in this way

现在,如果您使用Layout_marginLeft,Right等设置边距,则需要以这种方式更新边距

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

If you set margin using the new layout_marginStart, you need to update margin in this way

如果您使用 new 设置边距layout_marginStart,则需要以这种方式更新边距

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

Step 2, to update margin in dp

第 2 步,更新 dp 中的边距

All two ways of updating margin above are updating in pixels. You need to do a translation of dp to pixels.

以上两种更新边距的方式都是以像素为单位进行更新。您需要将 dp 转换为像素。

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

Now put the calculated value to the above margin update functions and you should be all set

现在把计算的值放到上面的保证金更新函数中,你应该都设置好了

回答by Ian Wong

layout_margin is a constraint that a view child tell to its parent. However it is the parent's role to choose whether to allow margin or not. Basically by setting android:layout_margin="10dp", the child is pleading the parent view group to allocate space that is 10dp biggerthan its actual size. (padding="10dp", on the other hand, means the child view will make its own content 10dp smaller.)

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

Consequently, not all ViewGroups respect margin. The most notorious example would be listview, where the margins of items are ignored. Before you call setMargin()to a LayoutParam, you should always make sure that the current view is living in a ViewGroup that supports margin (e.g. LinearLayouot or RelativeLayout), and cast the result of getLayoutParams()to the specific LayoutParams you want. (ViewGroup.LayoutParamsdoes not even have setMargins()method!)

因此,并非所有 ViewGroup 都尊重 margin。最臭名昭著的例子是列表视图,其中项目的边距被忽略。在调用setMargin()LayoutParam之前,您应该始终确保当前视图位于支持边距(例如 LinearLayouot 或 RelativeLayout)的 ViewGroup 中,并将结果getLayoutParams()转换为您想要的特定 LayoutParams。(ViewGroup.LayoutParamssetMargins()方法都没有!)

The function below should do the trick. However make sure you substitute RelativeLayout to the type of the parent view.

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

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

回答by neferpitou

This method will let you set the Marginin DP

此方法将让您在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);
}

UPDATE

更新

You can change the parameter that suits your need.

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

回答by Morozov

In Kotlin it will look like this:

在 Kotlin 中,它看起来像这样:

val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams

回答by aldajo92

When you are in a custom View, you can use getDimensionPixelSize(R.dimen.dimen_value), in my case, I added the margin in LayoutParams created on initmethod.

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

In Kotlin

在科特林

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

in Java:

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

回答by Ridwan Bin Sarwar

Use this method to set margin in dp

使用此方法在 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();
    }
}

call the method :

调用方法:

setMargins(linearLayout,5,0,5,0);