简体   繁体   中英

android set margin programmatically

after i press a button, i would like to move a textfield programmatically from the actual position + 20 margin left.

this is my xml file:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="5dp"
    android:paddingBottom="5dp">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txtField"
        android:layout_below="@+id/txtField2"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginLeft="20dp"
        android:layout_toLeftOf="@+id/Seperator"
        android:layout_toStartOf="@+id/Seperator"
        android:layout_marginRight="10p" />

    ....


</RelativeLayout>

i tried this code:

parameter = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
parameter.setMargins(30, 32, 10, 0); // left, top, right, bottom
txtField.setLayoutParams(parameter);

this works semi optimal. is there an way to use all the values of an xml file and only change the margin left value programmatically?

Try this code:

parameter =  (RelativeLayout.LayoutParams) txtField.getLayoutParams();
parameter.setMargins(leftMargin, parameter.topMargin, parameter.rightMargin, parameter.bottomMargin); // left, top, right, bottom
txtField.setLayoutParams(parameter);

Yep,

Take for example the following method that updates the left margin of a given view:

public static void setMarginLeft(View v, int left) {
    ViewGroup.MarginLayoutParams params =   
                                (ViewGroup.MarginLayoutParams)v.getLayoutParams();
    params.setMargins(left, params.topMargin, 
                            params.rightMargin, params.bottomMargin);
}

If you use kotlin, this can be simplified by creating an extension function

fun View.setMarginLeft(leftMargin: Int) {
  val params = layoutParams as ViewGroup.MarginLayoutParams
  params.setMargins(left, params.topMargin, params.rightMargin, params.bottomMargin)
  layoutParams = params
}

Now all you need is a view, and this extension function can be used anywhere.

val textView = findViewById(R.id.textView)
val marginLeft = context.resources.getDimension(R.dimen.marginLeft).toInt()
textView.setMarginLeft(marginLeft)

Note: This extension function will leave all other margins intact, no margins will be overwritten

You can also try

ImageView _circle=(ImageView) findViewById(R.id.image);
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) _circle.getLayoutParams();
int _20 = (int)getResources().getDimension(R.dimen.image_margin); 
// Directly set 20
mlp.setMargins(_20, _20, _20, _20);

Extending @enyciaa answer: by using Kotlin you can use extensions, but instead create one extension function for each margin side, you can use nullable value for all sides and then fill only values that's not null:

fun View.setMargin(
    leftMargin: Int? = null,
    topMargin: Int? = null,
    rightMargin: Int? = null,
    bottomMargin: Int? = null
) {
    val params = layoutParams as ViewGroup.MarginLayoutParams

    params.setMargins(
        leftMargin ?: params.leftMargin,
        topMargin ?: params.topMargin,
        rightMargin ?: params.rightMargin,
        bottomMargin ?: params.bottomMargin
    )
    
    layoutParams = params
}

So if you want to set only left margin, you can do it by specifying parameter name like this:

textView.setMargin(leftMargin = marginValue)

This will work in Android 30

val textView = TextView(this)
val layoutParams = ViewGroup.MarginLayoutParams(10, 10)
layoutParams.marginStart = 5
textView.layoutParams = layoutParams

To set padding -

textView.setPadding(2, 2, 2, 2)

Just use these few lines of code in kotlin

val params = your_view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(dpToPx(80, this), dpToPx(0, this), dpToPx(0, this), dpToPx(0, this))

Here is the code for the function dpToPx

private fun dpToPx(dp: Int, context: Context): Int {
    val density = context.resources.displayMetrics.density
    return (dp.toFloat() * density).roundToInt()
}

If you are using fragment, use requireContext() as parameter for context. From activity, use this as context like I have done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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