简体   繁体   English

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

[英]Change the Right Margin of a View Programmatically?

Can this attribute be changed dynamically in Java code?可以在 Java 代码中动态更改此属性吗?

android:layout_marginRight

I have a TextView , that has to change its position some pixels to the left dynamically.我有一个TextView ,它必须动态地向左改变一些像素的位置。

How to do it programmatically?如何以编程方式做到这一点?

EDIT: A more generic way of doing this that doesn't rely on the layout type (other than that it is a layout type which supports margins):编辑:这样做的更通用的方法不依赖于布局类型(除了它是支持边距的布局类型):

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

You should check the docs for TextView .您应该检查TextView的文档。 Basically, you'll want to get the TextView's LayoutParams object, and modify the margins, then set it back to the TextView.基本上,您需要获取 TextView 的 LayoutParams 对象,并修改边距,然后将其设置回 TextView。 Assuming it's in a LinearLayout, try something like this:假设它在 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);

I can't test it right now, so my casting may be off by a bit, but the LayoutParams are what need to be modified to change the margin.我现在无法测试它,所以我的演员表可能有点偏离,但需要修改 LayoutParams 以更改边距。

NOTE注意

Don't forget that if your TextView is inside, for example, a RelativeLayout , one should use RelativeLayout.LayoutParams instead of LinearLayout.LayoutParams不要忘记,如果你的 TextView 在里面,例如,一个RelativeLayout ,你应该使用RelativeLayout.LayoutParams而不是 LinearLayout.LayoutParams

Update: Android KTX更新:Android KTX

The Core KTX module provides extensions for common libraries that are part of the Android framework, androidx.core.view among them. Core KTX 模块为 Android 框架中的公共库提供扩展,其中包括androidx.core.view

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

The following extension functions are handy to deal with margins:以下扩展函数可以方便地处理边距:

Note: they are all extension functions of MarginLayoutParams , so first you need to get and cast the layoutParams of your view:注意:它们都是MarginLayoutParams扩展函数,所以首先你需要获取并layoutParams你的视图的layoutParams

 val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)

Sets the margins of all axes in the ViewGroup 's MarginLayoutParams .设置ViewGroupMarginLayoutParams中所有轴的MarginLayoutParams (The dimension has to be provided in pixels, see the last section if you want to work with dp) (必须以像素为单位提供尺寸,如果要使用 dp,请参阅最后一节)

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

Updates the margins in the ViewGroup 's ViewGroup.MarginLayoutParams .更新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)

Updates the relative margins in the ViewGroup 's MarginLayoutParams (start/end instead of left/right).更新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)

The following extension properties are handy to get the current margins:以下扩展属性可方便地获取当前边距:

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
  • Using dp instead of px :使用dp而不是px

If you want to work with dp (density-independent pixels) instead of px , you will need to convert them first.如果要使用dp (与密度无关的像素)而不是px ,则需要先转换它们。 You can easily do that with the following extension property:您可以使用以下扩展属性轻松做到这一点:

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

Then you can call the previous extension functions like:然后你可以调用之前的扩展函数,如:

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

Old answer:旧答案:

In Kotlin you can declare an extension function like:在 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()
}

Then you can call it like:然后你可以这样称呼它:

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

Or:或者:

myView2.setMargins(topMarginDp = 8) 

Use LayoutParams (as explained already).使用 LayoutParams(如前所述)。 However be careful which LayoutParams to choose.但是要小心选择哪个 LayoutParams。 According to https://stackoverflow.com/a/11971553/3184778 "you need to use the one that relates to the PARENT of the view you're working on, not the actual view"根据https://stackoverflow.com/a/11971553/3184778, “您需要使用与您正在处理的视图的父级相关的视图,而不是实际视图”

If for example the TextView is inside a TableRow, then you need to use TableRow.LayoutParams instead of RelativeLayout or LinearLayout例如,如果 TextView 在 TableRow 内,那么您需要使用 TableRow.LayoutParams 而不是 RelativeLayout 或 LinearLayout

Use This function to set all Type of margins使用此功能设置所有边距类型

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM