以编程方式更改视图的右边距?


172

可以在Java代码中动态更改此属性吗?

android:layout_marginRight

我有一个TextView,必须将其位置动态地向左更改一些像素。

如何以编程方式进行?

Answers:


462

编辑:一种不依赖于布局类型的更通用的方法(除了它是一种支持边距的布局类型):

public static void setMargins (View v, int l, int t, int r, int b) {
    if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
        p.setMargins(l, t, r, b);
        v.requestLayout();
    }
}

您应该检查文档中的TextView。基本上,您将需要获取TextView的LayoutParams对象,并修改边距,然后将其设置回TextView。假设它在LinearLayout中,请尝试如下操作:

TextView tv = (TextView)findViewById(R.id.my_text_view);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, 0, 10, 0); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);

我现在无法对其进行测试,因此我的转换可能会有点偏离,但是需要修改LayoutParams来更改边距。

注意

不要忘记,如果您的TextView位于其中,例如 RelativeLayout,则应使用RelativeLayout.LayoutParams而不是LinearLayout.LayoutParams


39
只是为了详细说明您的答案,以防其他人正在寻找这个答案。如果要以编程方式创建TextView,则还需要创建一个新的LinearLayout.LayoutParams对象,而不是尝试通过.getLayoutParams();来创建一个对象。
Ares

这很棒,看起来好像以像素设置边距。可以在dp中设置它吗?
SirRupertIII

3
@KKendall:只需先将DP转换为PX
凯文·科波克

根据您的注释:我有疑问。如果textview或按钮位于表格行内?那我应该用什么代替“相对布局”,“表布局”呢?
tejas 2013年

1
与该注释相关,您可以将tv.getLayoutParams()转换为ViewGroup.MarginLayoutParams。这样,只要实现边距,什么布局都没关系
Radu Simionescu 2014年

17

使用LayoutParams(如前所述)。但是要小心选择哪个LayoutParams。根据https://stackoverflow.com/a/11971553/3184778, “您需要使用与您正在处理的视图的PARENT相关的视图,而不是与实际视图相关的视图”

例如,如果TextView在TableRow中,则需要使用TableRow.LayoutParams而不是RelativeLayout或LinearLayout


感谢您的澄清!
Scott Biggs 2014年

1
真的很糟糕,您必须知道文本框目标位置才能设置边距...您会认为会有一种与目标位置无关的解决方案。
TatiOverflow '18 -10-29

10

使用此功能设置所有页边距类型

      public void setViewMargins(Context con, ViewGroup.LayoutParams params,      
       int left, int top , int right, int bottom, View view) {

    final float scale = con.getResources().getDisplayMetrics().density;
    // convert the DP into pixel
    int pixel_left = (int) (left * scale + 0.5f);
    int pixel_top = (int) (top * scale + 0.5f);
    int pixel_right = (int) (right * scale + 0.5f);
    int pixel_bottom = (int) (bottom * scale + 0.5f);

    ViewGroup.MarginLayoutParams s = (ViewGroup.MarginLayoutParams) params;
    s.setMargins(pixel_left, pixel_top, pixel_right, pixel_bottom);

    view.setLayoutParams(params);
}

2
为什么要增加0.5f?
behelit

2
@behelit我知道这已经晚了,但是对于任何寻找...的人,当您将浮标转换为整数时,浮标就会四舍五入。0.0-> 0.4舍入为0,而0.5-> 0.9舍入为1。这会在最终int中产生不一致。为避免这种情况,将0.5加到确保所有舍入为1。为什么?假设您的浮动值为0.3:0.3 + 0.5 = 0.8(向上舍入为1)。假设您的浮动值为0.8:0.8 + 0.5 = 1.3(向下舍入为1)。现在,您可以安全地了解最后的舍入了(请注意:我们加0.5而不是减,以避免得到负整数)
Psest328 '19

7

更新:Android KTX

所述核心KTX模块提供了扩展对于那些Android框架的一部分,公共库androidx.core.view其中。

dependencies {
    implementation "androidx.core:core-ktx:{latest-version}"
}

以下扩展功能可轻松处理页边距:

设置在所有轴的利润ViewGroupMarginLayoutParams。(尺寸必须以像素为单位,如果要使用dp,请参阅最后一节)

inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
params.setMargins(16)

更新的利润率在ViewGroupViewGroup.MarginLayoutParams

inline fun MarginLayoutParams.updateMargins(
    @Px left: Int = leftMargin, 
    @Px top: Int = topMargin, 
    @Px right: Int = rightMargin, 
    @Px bottom: Int = bottomMargin
): Unit
// Example: 8px left margin 
params.updateMargins(left = 8)

更新在相对边缘ViewGroupMarginLayoutParams(开始/结束,而不是左/右)。

inline fun MarginLayoutParams.updateMarginsRelative(
    @Px start: Int = marginStart, 
    @Px top: Int = topMargin, 
    @Px end: Int = marginEnd, 
    @Px bottom: Int = bottomMargin
): Unit
// E.g: 8px start margin 
params.updateMargins(start = 8)

以下扩展属性很容易获得当前边距:

inline val View.marginBottom: Int
inline val View.marginEnd: Int
inline val View.marginLeft: Int
inline val View.marginRight: Int
inline val View.marginStart: Int
inline val View.marginTop: Int
// E.g: get margin bottom
val bottomPx = myView1.marginBottom
  • 使用dp代替px

如果要使用dp(与密度无关的像素)代替px,则需要先进行转换。您可以使用以下扩展属性轻松地做到这一点:

val Int.px: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()

然后,您可以调用以前的扩展功能,例如:

params.updateMargins(start = 16.px, end = 16.px, top = 8.px, bottom = 8.px)
val bottomDp = myView1.marginBottom.dp

旧答案:

在Kotlin中,您可以声明扩展函数,例如:

fun View.setMargins(
    leftMarginDp: Int? = null,
    topMarginDp: Int? = null,
    rightMarginDp: Int? = null,
    bottomMarginDp: Int? = null
) {
    if (layoutParams is ViewGroup.MarginLayoutParams) {
        val params = layoutParams as ViewGroup.MarginLayoutParams
        leftMarginDp?.run { params.leftMargin = this.dpToPx(context) }
        topMarginDp?.run { params.topMargin = this.dpToPx(context) }
        rightMarginDp?.run { params.rightMargin = this.dpToPx(context) }
        bottomMarginDp?.run { params.bottomMargin = this.dpToPx(context) }
        requestLayout()
    }
}

fun Int.dpToPx(context: Context): Int {
    val metrics = context.resources.displayMetrics
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), metrics).toInt()
}

然后您可以这样称呼它:

myView1.setMargins(8, 16, 34, 42)

要么:

myView2.setMargins(topMarginDp = 8) 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.