1

I need to set programatically the height of a button as matchparent in my constraintLayout class.

open class Myword @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
     ) : ConstraintLayout(context,attrs) {

    var set = ConstraintSet()
    val tastoetim= Button(this.context)
    init{
        this.addView(tastoetim)
        tastoetim.requestLayout()


        set.connect(tastoetim.id, ConstraintSet.LEFT,this.id, ConstraintSet.LEFT, 10)
        set.connect(tastoetim.id, ConstraintSet.BOTTOM,this.id, ConstraintSet.BOTTOM, 0)

        tastoetim.minHeight = 0
        tastoetim.getLayoutParams().height= ViewGroup.LayoutParams.MATCH_PARENT

    } }

this does not work.

As already pointed out by author of this post (set height of imageview as matchparent programmatically), none of these answers works.

fisio
  • 494
  • 6
  • 12

3 Answers3

2

Resolved by firstly setting :

tastoetim.setMinHeight(0);
tastoetim.setMinimumHeight(0);

And then :

tastoetim.getLayoutParams().height= ViewGroup.LayoutParams.MATCH_PARENT;

setMinHeight is defined by ButtonView, while setMinimumHeight is defined by View. According to the docs, the greater of the two values is used, so both must be set.

fisio
  • 494
  • 6
  • 12
2

From the documentation for ConstraintLayout:

Important: MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent".

In my experience, using MATCH_PARENT can have some odd results.

In your case, you will want to do something like the following:

open class Myword @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {


    init {
        val tastoetim = Button(this.context)
        // The new Button needs an id, otherwise, it is "NO_ID" (-1)
        tastoetim.id = View.generateViewId()
        val lp = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT,
            ConstraintLayout.LayoutParams.MATCH_CONSTRAINT
        )
        this.addView(tastoetim, lp)

        // Get the ConstraintSet only after the view is added.
        val set = ConstraintSet()
        set.clone(this)

        set.connect(
            tastoetim.id,
            ConstraintSet.LEFT,
            ConstraintSet.PARENT_ID,
            ConstraintSet.LEFT,
            10
        )

        // For match constraints, we need a top and a bottom view to connect to. Here the
        // parent top is assumed, but it could be another view.
        set.connect(
            tastoetim.id,
            ConstraintSet.TOP,
            ConstraintSet.PARENT_ID,
            ConstraintSet.TOP,
            0
        )
        set.connect(
            tastoetim.id,
            ConstraintSet.BOTTOM,
            ConstraintSet.PARENT_ID,
            ConstraintSet.BOTTOM,
            0
        )

        // Apply the updated ConstraintSet back to the ConstraintLayout.
        set.applyTo(this)
    }
}
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • thank you for the explanation! in fact I was having trouble positioning the button. now it works! But when i add a second button, the first one disappears. what am i doing wrong? [link](https://codeshare.io/GbMB3O) – fisio Feb 17 '20 at 09:17
  • 1
    @AndreaDeSimone You are sharing a layout params between the two buttons. Each needs it's own since that is where the layout info is stored. A way to check your layouts is with the Layout Inspector (Tools->Layout Inspector). – Cheticamp Feb 17 '20 at 12:04
0

Another way is to set the height equal to the height of the parent.

Let's assume that the parent is a linear layout with id = layVert:

tastoetim.layoutParams.height = findViewById<LinearLayout>(R.id.layVert).layoutParams.height
cela
  • 2,352
  • 3
  • 21
  • 43
BorGhO
  • 3
  • 3
  • Of course, but in my case parent.height is wrap_content so child height needs to change accordingly – fisio Nov 13 '20 at 08:12