How to set weight dynamically in a constraint layout

Viewed 1283

I need to implement the equivalent of the following layout dynamically. The code I have tried works correctly for positions, the elements are align as I want, but the weight value does not change anything. I have not figured out how to make the seek bar shrink its width to give enough space to the switch button instead of pushing it on the side.

Xml equivalent of what I want to code dynamically :

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <no.beiningbogen.snute.common.view.TouchAwareSeekBar
        android:id="@+id/touchAwareSeekBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:dsb_indicatorColor="@color/discrete_seek_bar"
        app:dsb_progressColor="@color/discrete_seek_bar"
        app:dsb_scrubberHeight="5dp"
        app:dsb_thumbSize="20dp"
        app:dsb_trackColor="@color/colorMaterialGray300"
        app:dsb_trackHeight="5dp"
        app:layout_constraintEnd_toStartOf="@+id/device_switch"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.SwitchCompat
        android:id="@+id/device_switch"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:background="@null"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/touchAwareSeekBar"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is the code I implemented :

val layout = ConstraintLayout(context).apply {
        id = View.generateViewId()
        layoutParams = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )
    }

val dimLevelView = map[DeviceAttributeType.dimLevel]
val onView = map[DeviceAttributeType.on]

layout.addView(dimLevelView)
layout.addView(onOffView)

val set = ConstraintSet()
set.clone(layout)

set.connect(dimLevelView.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
set.connect(dimLevelView.id, ConstraintSet.END, onView.id, ConstraintSet.START)
set.connect(dimLevelView.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
set.centerVertically(dimLevelView.id, ConstraintSet.PARENT_ID)
set.setHorizontalWeight(dimLevelView.id, 1.toFloat())

set.connect(onView.id, ConstraintSet.START, dimLevelView.id, ConstraintSet.END)
set.connect(onView.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
set.connect(onView.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
set.centerVertically(onView.id, ConstraintSet.PARENT_ID)

set.applyTo(layout)

I get the dim and onOff views from xml :

<!-- one file to define this -->
<no.beiningbogen.snute.common.view.TouchAwareSeekBar
    android:id="@+id/touchAwareSeekBar"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:dsb_indicatorColor="@color/discrete_seek_bar"
    app:dsb_progressColor="@color/discrete_seek_bar"
    app:dsb_scrubberHeight="5dp"
    app:dsb_thumbSize="20dp"
    app:dsb_trackColor="@color/colorMaterialGray300"
    app:dsb_trackHeight="5dp" />

<!-- in another file -->
<androidx.appcompat.widget.SwitchCompat
    android:id="@+id/device_switch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@null" />

What do i need to modify to force the seek bar to take the remaining space next to the switch instead of pushing it ?

1 Answers

The code is almost correct. You don't specify a start constraint to the SeekBar so it vanishes along with everything else. Try the following:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(createLayout())
        supportActionBar?.setTitle("")

    }

    fun createLayout(): ConstraintLayout {

        val layout = ConstraintLayout(this).apply {
            id = View.generateViewId()
            layoutParams = ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.MATCH_PARENT,
                ConstraintLayout.LayoutParams.WRAP_CONTENT
            )
        }

        val dimLevelView = LayoutInflater.from(this).inflate(R.layout.seekbar_widget, layout, false)
        val onView = LayoutInflater.from(this).inflate(R.layout.switch_widget, layout, false)

        layout.addView(dimLevelView)
        layout.addView(onView)

        val set = ConstraintSet()
        set.clone(layout)

        set.connect(
            dimLevelView.id,
            ConstraintSet.START,
            ConstraintSet.PARENT_ID,
            ConstraintSet.START
        )

        set.connect(
            dimLevelView.id,
            ConstraintSet.START,
            ConstraintSet.PARENT_ID,
            ConstraintSet.START
        )
        set.connect(dimLevelView.id, ConstraintSet.END, onView.id, ConstraintSet.START)
        set.connect(dimLevelView.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
        set.centerVertically(dimLevelView.id, ConstraintSet.PARENT_ID)
        set.setHorizontalWeight(dimLevelView.id, 1.toFloat())

        set.connect(onView.id, ConstraintSet.START, dimLevelView.id, ConstraintSet.END)
        set.connect(onView.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
        set.connect(onView.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
        set.centerVertically(onView.id, ConstraintSet.PARENT_ID)

        set.applyTo(layout)
        return layout
    }
}
Related