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

Nul*_*ion 158 layout android textview

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

android:layout_marginRight
Run Code Online (Sandbox Code Playgroud)

我有一个TextView,必须动态地将其位置改为左侧的一些像素.

如何以编程方式执行?

kco*_*ock 438

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您应该检查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);
Run Code Online (Sandbox Code Playgroud)

我现在无法测试它,所以我的演员可能会稍微偏离,但LayoutParams是需要修改以更改边距的内容.

注意

不要忘记,如果你的TextView在里面,例如, RelativeLayout,那么应该使用RelativeLayout.LayoutParams而不是LinearLayout.LayoutParams

  • 只是为了详细说明你的答案,以防其他人正在寻找这个.如果您以编程方式创建TextView,那么您还需要创建一个新的LinearLayout.LayoutParams对象,而不是尝试通过.getLayoutParams()获取一个. (36认同)
  • @KKendall:只需先[将DP转换为PX](http://stackoverflow.com/a/6327095/321697)。 (3认同)
  • 与注释相关,您可以将 tv.getLayoutParams() 转换为 ViewGroup.MarginLayoutParams。这样,父布局是什么并不重要,只要它实现边距即可 (2认同)

Dav*_*uel 25

更新:Android KTX

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

dependencies {
    implementation "androidx.core:core-ktx:{latest-version}"
}
Run Code Online (Sandbox Code Playgroud)

以下扩展函数可以方便地处理边距:

注意:它们都是 的扩展函数MarginLayoutParams,所以首先你需要获取并转换layoutParams你的视图:

val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
Run Code Online (Sandbox Code Playgroud)

设置ViewGroup's中所有轴的边距MarginLayoutParams。(必须以像素为单位提供尺寸,如果要使用 dp,请参阅最后一节)

inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
params.setMargins(16)
Run Code Online (Sandbox Code Playgroud)

更新ViewGroup's 中的边距ViewGroup.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)
Run Code Online (Sandbox Code Playgroud)

更新ViewGroup's 中的相对边距MarginLayoutParams(开始/结束而不是左/右)。

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)
Run Code Online (Sandbox Code Playgroud)

以下扩展属性可方便地获取当前边距:

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
Run Code Online (Sandbox Code Playgroud)
  • 使用dp代替px

如果要使用dp(密度无关像素)而不是px,则需要先转换它们。您可以使用以下扩展属性轻松做到这一点:

val Int.px: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()
Run Code Online (Sandbox Code Playgroud)

然后你可以调用之前的扩展函数,如:

params.updateMargins(start = 16.px, end = 16.px, top = 8.px, bottom = 8.px)
val bottomDp = myView1.marginBottom.dp
Run Code Online (Sandbox Code Playgroud)

旧答案:

在 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()
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样称呼它:

myView1.setMargins(8, 16, 34, 42)
Run Code Online (Sandbox Code Playgroud)

或者:

myView2.setMargins(topMarginDp = 8) 
Run Code Online (Sandbox Code Playgroud)

  • 对于第一个答案,请添加完整的代码示例 (2认同)

kou*_*nho 15

使用LayoutParams(已经说明).但是要小心选择哪个LayoutParams.根据/sf/answers/838008741/ "您需要使用与您正在处理的视图的PARENT相关的那个,而不是实际视图"

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


小智 9

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

      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);
}
Run Code Online (Sandbox Code Playgroud)

  • @behelit 我知道这已经晚了,但对于任何正在寻找的人来说...... 0.0 -> 0.4 舍入为 0,而 0.5 -> 0.9 舍入为 1。这可能会导致最终整数不一致。为了防止这种情况,添加 0.5 可确保所有舍入为 1。为什么?假设您的浮动是 0.3:0.3 + 0.5 = 0.8,向上取整为 1。假设您的浮动为 0.8:0.8 + 0.5 = 1.3,向下取整为 1。现在您可以安全地了解最后的四舍五入(边注:我们添加 0.5 而不是减去以避免得到负整数) (3认同)
  • 为什么要额外增加 0.5f? (2认同)