在this,this和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
}
我希望边距重置为-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
,没有属性topMargin
,bottomMargin
,leftMargin
,rightMargin
。您看到的mc实例只是一个MarginContainer
,它包含偏移(-3dp)边距和(oml,omr,omt,omb)和原始边距(ml,mr,mt,mb)。
您应该使用LayoutParams
设置按钮边距:
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);
根据您使用的布局,您应该使用RelativeLayout.LayoutParams
或LinearLayout.LayoutParams
。
要将dp度量转换为像素,请尝试以下操作:
Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
yourdpmeasure,
r.getDisplayMetrics()
);
用于快速单线设置使用
((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);
但要小心对LayoutParams的任何错误使用,因为这将没有qazxsw poi语句实例chech
就像今天一样,最好的可能是使用由AirBnB提供的if
库。
然后可以像这样应用样式:
Paris
它还支持使用注释的自定义视图(如果您扩展视图):
Paris.style(myView).apply(R.style.MyStyle);
@Styleable and @Style
我不得不把它扔给((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
linearLayout.setBackgroundResource(R.drawable.smartlight_background);
一个linearLayout,因为它继承了它并在那里设置了边距,所以活动只出现在屏幕的一部分上,并且背景与FrameLayout
中的原始布局参数不同。
setContentView
其他人都没有使用相同的活动,并根据从不同菜单打开活动来更改边距! setLayoutParams对我来说从未起作用 - 设备每次都会崩溃。即使这些是硬编码的数字 - 这仅仅是用于演示目的的代码示例。
为那些可能觉得方便的人创建了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);
在我的例子中,我以编程方式将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 }
}
}
您可以使用此方法并根据您的设备将静态维数(如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);
更新:
就像你曾经使用 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的值。顺时针!,从左边开始。
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
最好的方式:
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);
第1步,更新保证金
基本的想法是获得保证金,然后更新它。更新将自动应用,您无需将其重新设置。要获取布局参数,只需调用此方法:
LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();
LayoutParams
来自您的视图布局。如果视图来自线性布局,则需要导入LinearLayout.LayoutParams
。如果使用相对布局,请导入LinearLayout.LayoutParams
等。
现在,如果你使用Layout_marginLeft
,Right
等设置保证金,你需要以这种方式更新保证金
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;
现在将计算值放到上面的边际更新函数中,您应该全部设置
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);
}
此方法可让您在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
您可以更改适合您需要的参数。
当你在自定义视图中,你可以使用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);
}
}
使用此方法在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);