Search code examples
androiddynamickotlinruntimelayoutmargins

Update layout_margin inside kotlin class for specific elements


So, this should be pretty basic, but I am new to Kotlin. So I basically have the following ImageView inside a RelativeLayout view.

<ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            app:srcCompat="@drawable/moon_0"
            android:id="@+id/imagen_luna"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp" 
            android:layout_alignParentStart="true"
            android:layout_alignParentEnd="true" 
            android:layout_alignParentBottom="true"
            android:layout_alignParentTop="true" />

The thing is that under certain condition this ImageView can collide visually with another element, so I have to modify the marginStart and the marginEnd properties. I saw in some tutorials that first I must obtain the current layout margins or something like that, but I am not sure why it's so complicated, in Swift I just modify the properties of each margin.

Is there an easy way to achieve this or in case there isn't what would be the easiest way to do this?

UPDATE - Added code in the Adapter

This is the code I have in my adapter for this specific ImageView:

override fun onBindViewHolder(holder: AnoViewHolder, position: Int) {
    ...
    if(respec.nombre_icono_signo != "" && respec.imagen_luna != "") {
        val layoutParamsLuna = holder.view?.imagen_luna.layoutParams as RelativeLayout.LayoutParams
        layoutParamsLuna.setMargins(1, 8, 15, 8)
        holder.view?.imagen_luna.layoutParams = layoutParamsLuna
    }
    ...
}

The thing is that this does nothing and my theory is that the setMargins function accepts left and right margins, not start and end margins.


Solution

  • You can update margin in layoutParams of view

    Ex:

        val layoutParams= imagen_luna.layoutParams as RelativeLayout.LayoutParams
        layoutParams.marginEnd=resources.getDimension(your_dimension).toInt()
        layoutParams.marginStart=resources.getDimension(your_dimension).toInt()
    
        layoutParams.bottomMargin=resources.getDimension(your_dimension).toInt()
        layoutParams.topMargin=resources.getDimension(your_dimension).toInt()
    
        //or
    
        layoutParams.setMargins(start,top,end,bottom)
    
        imagen_luna.layoutParams=layoutParams
    

    You have to add value for margins in dimension file.because if you set setMargins(1, 8, 15, 8) like this,It's will margin in pixel not in dp.

    So use margin values like below.

    <dimen name="spacing_normal">16dp</dimen>
    <dimen name="spacing_small">8dp</dimen>
    <dimen name="spacing_tiny">4dp</dimen>
    

    Update your dapter class like belo

    override fun onBindViewHolder(holder: AnoViewHolder, position: Int) {
    ...
    if(respec.nombre_icono_signo != "" && respec.imagen_luna != "") {
        val layoutParamsLuna = holder.view?.imagen_luna.layoutParams as RelativeLayout.LayoutParams
        layoutParamsLuna.setMargins(context.resources.getDimension(R.dimen.spacing_normal).toInt(), 
               context.resources.getDimension(R.dimen.spacing_normal).toInt(), 
               context.resources.getDimension(R.dimen.spacing_normal).toInt(),
               context.resources.getDimension(R.dimen.spacing_normal).toInt())
        holder.view?.imagen_luna.layoutParams = layoutParamsLuna
    }else{
      //reset margin for else case because recylerview reuse views so it's will keep previous states
    }
    ...
    }