Search code examples
androidandroid-constraintlayout

androidStudio : add multiple elements to ConstraintLayout programmatically


I have set up a new project in android studio. Compatibility Android 9 Java.

I want to add multiple elements in a for loop to the view / layout.

Does this work with ConstraintLayout or do i have to switch the whole project to LinearLayout?

This does not work and the TextView items are not shown:

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;

import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        createTextViews();
    }



    private void createTextViews() {
        for (int i = 0; i < 10; i++) {


        ConstraintLayout constraintLayout = findViewById(R.id.MainActivity);
            //constraintLayout.setId(ConstraintLayout.generateViewId());
            ConstraintSet set = new ConstraintSet();

            TextView tv = new TextView(this);
            tv.setText("sdfs");
            tv.setTextSize(45);
            tv.setId(TextView.generateViewId());

            ConstraintLayout.LayoutParams cltv = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
            tv.setLayoutParams(cltv);

            constraintLayout.addView(tv,0);

            set.clone(constraintLayout);
            set.connect(tv.getId(), ConstraintSet.TOP, constraintLayout.getId(), ConstraintSet.TOP, 60);
            set.applyTo(constraintLayout);
  }
}

Solution

  • If you want to add views to a constraint layout programmatically, you also have to add constraints so they show up correctly. For example, here is how you could set a vertical stack of text views.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        ConstraintLayout cl = findViewById(R.id.parent_constraint);
        int lastId = -1;
    
        // first add the views
        for (int i = 0; i < 10; i++) {
            TextView tv = new TextView(this);
            tv.setText("Entry " + i);
            tv.setTextSize(20);
            int id = TextView.generateViewId();
            tv.setId(id);
    
            ConstraintLayout.LayoutParams cltv = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
            
            // you can add constraints here, or save off a list of 
            // the view IDs and set up constraints in a separate step
            cltv.startToStart = ConstraintSet.PARENT_ID;
            cltv.endToEnd = ConstraintSet.PARENT_ID;
    
            // for the first view, constrain it to the top,
            // subsequent views get stacked below the previous one
            if( i == 0 ) {
                cltv.topToTop = ConstraintSet.PARENT_ID;
            }
            else {
                cltv.topToBottom = lastId;
            }
            tv.setLayoutParams(cltv);
    
            cl.addView(tv);
            lastId = id;
        }
    }
    

    If you want to do the creation first, save off a list of view IDs, then the layout (for a more complicated layout) you can use a ConstraintSet like this

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        ConstraintLayout cl = findViewById(R.id.parent_constraint);
        ArrayList<Integer> ids = new ArrayList<>();
    
        // first create and add the views to the constraint layout
        for (int i = 0; i < 10; i++) {
            TextView tv = new TextView(this);
            tv.setText("Entry " + i);
            tv.setTextSize(20);
            int id = TextView.generateViewId();
            tv.setId(id);
            ids.add(id);
    
            ConstraintLayout.LayoutParams cltv = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
    
            tv.setLayoutParams(cltv);
    
            cl.addView(tv);
        }
    
        // Then set constraints
        ConstraintSet set = new ConstraintSet();
        set.clone(cl);
    
        for (int i = 0; i < 10; i++) {
    
            // start_toStartOf=parent
            set.connect(ids.get(i), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0);
    
            // end_toEndOf=parent
            set.connect(ids.get(i), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);
    
            if( i == 0 ) {
                //top_toTopOf=parent
                set.connect(ids.get(i), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0);
            }
            else {
                //top_toBottomOf=view[n-1]
                set.connect(ids.get(i), ConstraintSet.TOP, ids.get(i-1), ConstraintSet.BOTTOM, 0);
            }
        }
    
        set.applyTo(cl);
    }