Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the Right Margin of a View Programmatically?

Can this attribute be changed dynamically in Java code?

android:layout_marginRight

I have a TextView, that has to change its position some pixels to the left dynamically.

How to do it programmatically?

like image 930
NullPointerException Avatar asked Sep 29 '22 23:09

NullPointerException


People also ask

How do I set margins to recyclerView programmatically?

margin); int marginTopPx = (int) (marginTopDp * getResources(). getDisplayMetrics(). density + 0.5f); layoutParams. setMargins(0, marginTopPx, 0, 0); recyclerView.

How do you set margin top programmatically?

You should use LayoutParams to set your button margins: LayoutParams params = new LayoutParams( LayoutParams. WRAP_CONTENT, LayoutParams. WRAP_CONTENT ); params.


2 Answers

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

like image 512
Kevin Coppock Avatar answered Oct 08 '22 13:10

Kevin Coppock


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:

Note: they are all extension functions of MarginLayoutParams, so first you need to get and cast the layoutParams of your view:

val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
  • 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
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) 
like image 45
David Miguel Avatar answered Oct 08 '22 13:10

David Miguel