在Android中,我怎么在DP设置边距编程?(In Android, how do I set m

2019-06-18 10:37发布

在此 , 这个和这个线程我试图找到如何设置一个单一的视图边缘的答案。 然而,我在想,如果没有一个更简单的方法。 我会解释为什么我宁愿不希望使用这种方法:

我有延伸按钮自定义按钮。 如果背景被设置为默认的背景别的东西(通过调用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,我宁愿没有他得到他的父母和检查的instanceof该父。 这也将是相当inperformant,我想象。

此外,当调用(使用的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 ,不具有的属性topMarginbottomMarginleftMarginrightMargin 。 您所看到的MC实例只是一个MarginContainer包含偏移(-3dp)利润率和(OML,OMR,OMT,OMB)和原来的利润(ML,MR,MT,MB)。

Answer 1:

您应该使用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()
);


Answer 2:

的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



Answer 3:

曾经最好的方法:

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

希望这会帮助你。



Answer 4:

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


Answer 5:

layout_margin是一个约束,一个视图孩子告诉其父。 然而,它是父母的选择是否允许保证金或没有作用。 基本上通过设置机器人:layout_margin =“10dp”,孩子恳求父视图组分配空间比它的实际大小更大的10dp。 (填充=“10dp”,而另一方面,意味着子视图将自己的内容10dp小 。)

因此, 并不是所有的ViewGroups尊重保证金 。 最臭名昭著的例子是列表视图,在项目的利润率将被忽略。 致电前setMargin()到LayoutParam,你应该始终确保当前视图是生活在支持保证金(如LinearLayouot或RelativeLayout的)一个ViewGroup中,投出的结果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);
}


Answer 6:

这个方法可以让你设定的保证金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

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



Answer 7:

这里是所有功能于一身的答案最近更新:

步骤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;

现在把计算出的值以上保证金更新功能,你应该准备就绪



Answer 8:

当你在一个自定义的视图,您可以使用getDimensionPixelSize(R.dimen.dimen_value)在我的情况,我加入了利润率上创建的LayoutParams init方法。

在科特林

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


Answer 9:

对于一个快速行安装使用

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

但要carfull对任何错误使用到的LayoutParams,因为这将有没有if statment情况下再检查一下



Answer 10:

截至今天,最好的可能是使用巴黎 ,由制作的Airbnb提供一个图书馆。

那么样式可以应用这样的:

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

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

@Styleable and @Style


Answer 11:

使用此方法来设置保证金的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);


Answer 12:

((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

我不得不矿投来FrameLayout的LinearLayout中,因为它从它继承等活动仅出现在使用不同的背景比原来的布局PARAMS沿着屏幕的一部分设置页边距那里setContentView

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

其他人都没有工作了使用相同的活动以及基于从不同的菜单打开该活动的空间! setLayoutParams从来没有为我工作 - 该设备将崩溃每一次。 尽管这些都是硬编码的数字 - 这只是仅供演示代码的一个例子。



Answer 13:

创建,对于那些你谁可能会觉得得心应手科特林扩展功能。

确保像素不DP到通过。 编码愉快:)

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


文章来源: In Android, how do I set margins in dp programmatically?