Change the Right Margin of a View Programmatically?

后端 未结 4 2097
野性不改
野性不改 2020-11-30 18:04

Can this attribute be changed dynamically in Java code?

android:layout_marginRight

I have a TextView, that has to change its

相关标签:
4条回答
  • 2020-11-30 18:39

    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. Basically, you'll want to get the TextView's LayoutParams object, and modify the margins, then set it back to the TextView. Assuming it's in a LinearLayout, try something like this:

    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.

    NOTE

    Don't forget that if your TextView is inside, for example, a RelativeLayout, one should use RelativeLayout.LayoutParams instead of LinearLayout.LayoutParams

    0 讨论(0)
  • 2020-11-30 18:41

    Use LayoutParams (as explained already). However be careful which LayoutParams to choose. 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"

    If for example the TextView is inside a TableRow, then you need to use TableRow.LayoutParams instead of RelativeLayout or LinearLayout

    0 讨论(0)
  • 2020-11-30 18:48

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 18:56

    Update: Android KTX

    The Core KTX module provides extensions for common libraries that are part of the Android framework, androidx.core.view among them.

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

    The following extension functions are handy to deal with margins:

    • setMargins() extension function:

    Sets the margins of all axes in the ViewGroup's MarginLayoutParams. (The dimension has to be provided in pixels, see the last section if you want to work with dp)

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

    Updates the margins in the 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)
    
    • updateMarginsRelative() extension function:

    Updates the relative margins in the ViewGroup's MarginLayoutParams (start/end instead of left/right).

    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:

    If you want to work with dp (density-independent pixels) instead of px, you will need to convert them first. 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:

    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) 
    
    0 讨论(0)
提交回复
热议问题