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

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

我有一个自定义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(我已经在这里阅读了如何将像素转换为dp,所以一旦我知道如何在px中设置边距,我可以自己pipe理转换)。 但是因为这是在CustomButton类中调用的,父类可以从LinearLayout到TableLayout不同,我不希望他得到他的父类,并检查父类的实例。 我想,这也是相当不利的。

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

问: 除了使用LayoutParams之外,是否有更简单的方法来以编程方式设置单个button的边距

编辑:我知道的LayoutParams的方式,但我想避免处理每个不同的容器types的解决scheme:

 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实例只是包含偏移(-3dp)页边距和(oml,omr,omt,omb)和原始页边距(ml,mr,mt,mb)的MarginContainer。

您应该使用LayoutParams设置您的button边距:

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

LayoutParams – 不工作! ! !

需要使用types: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

最好的方式:

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

希望这会帮助你。

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

layout_margin是一个视图的孩子告诉其父母的约束。 但是,select是否允许保证金是父母的责任。 基本上通过设置android:layout_margin =“10dp”,孩子正在请求父视图组分配比实际大小大10dp的空间。 (填充=“10dp”,另一方面,意味着子视图将使自己的内容10dp更小)

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

下面的函数应该做的伎俩。 但是请确保将RelativeLayoutreplace为父视图的types。

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

这个方法可以让你在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

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