Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a constraint layout which I am adding lines to (I don't know how many lines will be added hence I do this in code rather than XML).

The fields are arranged with weights to give different size priorities and I use a Horizontal chain to add the first line (testing using simple text fields). This works well and I get what I expect, but adding the next line is proving problematic.
Here's the pertinent code...
        var cLayout = ConstraintLayout(context!!)
        cLayout.layoutParams = ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
.......//Set background lurid colour - can see if the layout changes
        cLayout.setBackgroundColor(Color.YELLOW)
.......//First Field to add
        val txtTitle = addChainField( "Title", Theme.Hdg)
        txtTitle.setPadding(25,0,0,0) //move a little from screen edge
        cLayout.addView(txtTitle)
        val txtStyle = addChainField( "Style", Theme.Hdg)
        cLayout.addView(txtStyle)
.......//three other fields added in exactly the same way different strings
         .//And this all works.....
         .//
.......//Now the tricky bit - get a set, clone it and make 2 arrays
.......//First array... Weights - which gives us field sizes
.......//Second array  Id's of the fields.
        var set = ConstraintSet()
        set.clone(cLayout)
        var weights = floatArrayOf(5f, 2f,1f,2f,2.5f)
        var ids = intArrayOf(txtTitle.id, txtStyle.id, txtSize.id, txtColour.id, txtBG.id)
.......//Now we create a horizontal chain - this works admirably
        set.createHorizontalChain(ConstraintSet.PARENT_ID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT,
        ids, weights, ConstraintSet.HORIZONTAL)
.......//Adding a field which should go on a line BELOW...
.......//I don't know if I can simply connect the constraints here
        val txtMain = addField("Main Title", Theme.Txt)
...//This next line is the problem - without it puts the field at top left...
...//With this line it doesn't appear at all and the layout extends down...
        set.connect(txtMain.id, ConstraintSet.TOP, txtTitle.id, ConstraintSet.BOTTOM)
        cLayout.addView(txtMain)
.......//After adding the view, apply the set
        set.applyTo(cLayout)


So - what happens... If I add the field "Main Title with no constraints
Obviously it goes to the top left of the constraint layout and overwrites the initial Title field.

IF I add the set.connect to connect the new field's TOP with the txtTitle field's BOTTOM (which should put it below the txtTitle field)....
Then I get the first line correct and then the yellow of the layout extends about 10-15 lines equivalent downwards without showing the new field.


For completeness, here are the called functions -


    private fun addChainField(name: String, fType: TextMetrics): TextView{
        val fld = createTextView(context!!, name, fType.TxtStyle, fType.TxtSz, fType.TxtClr)
        fld.layoutParams = createLayoutParams(RelativeLayout.CENTER_VERTICAL,  null)
        fld.layoutParams.width = 0  //must be zero for weights....
        return fld
    }
    private fun addField(name:String, fType: TextMetrics): TextView{
        val fld = createTextView(context!!, name, fType.TxtStyle, fType.TxtSz, fType.TxtClr)
        fld.layoutParams = createLayoutParams(RelativeLayout.CENTER_VERTICAL,  null)
        return fld
    }

fun createLayoutParams(rule: Int, subject: Int?) : RelativeLayout.LayoutParams {
    val lp = RelativeLayout.LayoutParams(
        RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT
    )
    if (subject != null){lp.addRule(rule, subject)}
    else {lp.addRule(rule)}
    return lp
}

fun createTextView(ctx: Context, txt: String, tFace: Int, size: Float, vColor: Int) : TextView {
    val txtView = TextView(ctx)
    txtView.text = txt
    txtView.textSize = size
    txtView.setTextColor(vColor)
    txtView.setTypeface(null, tFace)
    txtView.id = View.generateViewId()
    return txtView
}


What I have tried:

With the constraint line below - the output doesn't show the txtMain field at all - however, the constraint layout is extended downwards by about 10-15 lines worth of space.
set.connect(txtMain.id, ConstraintSet.TOP, txtTitle.id, ConstraintSet.BOTTOM)

When this line is NOT included....
The txtMain Field is shown overwriting the txtTitle field.

I did wonder about doing a second constraint layout - but that kinda defeats the purpose of a constraint layout being flat and wanted to get as many fields in a flat format as possible.

Thus, what I want to achieve is several lines of fields one underneath each other and my initial idea was to use a chain to enable the weights to be added and position the initial fields.... Then to simply put the next line field by field below the first using constraint.TOP to constraint.BOTTOM.

If anyone has any ideas, I would be very grateful.

Thanks.
Posted
Updated 17-May-23 12:12pm

1 solution

Simple mistake - can't see the wood for the trees.
Although to be fair, it's my first Constraint Layout - I have previously
used Relative Layouts exclusively.
I thought the problem was something to do with the Horizontal chain.
However, upon taking out the horizontal chain - same thing happened.

Investigation pointed to the constraint set as with no constraint set
it put the field at the top left, and when the constraint set was put in
it vanished.

I had previously used this set.connect statement to place it below the existing Title heading.
set.connect(txtMain.id, ConstraintSet.TOP, txtTitle.id, ConstraintSet.BOTTOM)

Without this, the field appeared at top left in the constraint layout.
With this it simply vanished.

however, what I failed to do was add the left, right and bottom constraints - as below
set.connect(txtMain.id, ConstraintSet.TOP, txtTitle.id, ConstraintSet.BOTTOM)
set.connect(txtMain.id, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
set.connect(txtMain.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
set.connect(txtMain.id, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)

If I put ALL of these in - it works and the MainTitle is correctly positioned below the field.
If I miss ANY of these 4, it simply vanishes.. I suspect that it sizes the field to zero - despite the fact that I used my addField function rather than the addChainField (the addChainField sets width to zero to allow for weight constraints which are needed in a chain).

This now seems to work perfectly.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900