本文翻译自:In Android, how do I set margins in dp programmatically?
In this , this and this thread 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. 我有一个自定义按钮,它扩展了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: 如果背景设置为默认背景以外的其他值(通过调用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 here how to convert from pixels to dp, so once I know how to set margins in px, I can manage the conversion myself). 我希望将页边距重置为-3dp(我已经在这里阅读了如何从像素转换为dp,因此一旦知道如何在px中设置页边距,就可以自己管理转换了)。 But since this is called in the CustomButton
class, the parent can vary from LinearLayout to TableLayout, and I'd rather not have him get his parent and check the instanceof that parent. 但是由于这是在CustomButton
类中调用的,因此父级可以从LinearLayout到TableLayout有所不同,而我宁愿不要让他获得其父级并检查该父级的实例。 That'll also be quite inperformant, I imagine. 我想那也将表现不佳。
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();
因为this.getLayoutParams();
returns a ViewGroup.LayoutParams
, which do not have the attributes topMargin
, bottomMargin
, leftMargin
, rightMargin
. 返回一个ViewGroup.LayoutParams
,它没有属性topMargin
, bottomMargin
, leftMargin
, rightMargin
。 The mc instance you see is just a MarginContainer
which contains offset (-3dp) margins and (oml, omr, omt, omb) and the original margins (ml, mr, mt, mb). 您看到的mc实例只是MarginContainer
,其中包含偏移量(-3dp)边距和(oml,omr,omt,omb)和原始边距(ml,mr,mt,mb)。
参考:https://stackoom.com/question/rPCR/在Android中-如何以编程方式在dp中设置边距
You should use LayoutParams
to 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.LayoutParams
or LinearLayout.LayoutParams
. 根据您使用的布局,应使用RelativeLayout.LayoutParams
或LinearLayout.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()
);
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
layout_margin is a constraint that a view child tell to its parent. layout_margin是视图子项告诉其父项的约束。 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 bigger than its actual size. 基本上,通过设置android:layout_margin =“ 10dp”,孩子将请求父视图组分配比其实际大小大10dp的空间。 (padding="10dp", on the other hand, means the child view will make its own content 10dp smaller .) (另一方面,padding =“ 10dp”表示子视图将使其自身的内容缩小10dp 。)
Consequently, not all ViewGroups respect margin . 因此, 并非所有ViewGroup都遵守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 (eg LinearLayouot or RelativeLayout), and cast the result of getLayoutParams()
to the specific LayoutParams you want. 在将setMargin()
调用到LayoutParam之前,应始终确保当前视图位于支持margin的ViewGroup中(例如LinearLayouot或RelativeLayout),并将getLayoutParams()
的结果getLayoutParams()
为所需的特定LayoutParams。 ( ViewGroup.LayoutParams
does not even have setMargins()
method!) ( ViewGroup.LayoutParams
甚至没有setMargins()
方法!)
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);
}
This method will let you set the Margin in DP 此方法可让您在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 更新
You can change the parameter that suits your need. 您可以更改适合您需要的参数。
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);