add Dynamic child views vertically to ConstraintLayout
Asked Answered
T

1

6

Android ViewGroup has the following methods to add (child) Views:

enter image description here

I know we can easily define horizontal/vertical orientation to LinearLayout in xml/programatically and add child views, eg.

enter image description here

Similarly with RelativeLayout, we can use ViewGroup's addView and RelativeLayout.LayoutParams's method:

enter image description here

I am also aware that we can use LinearLayout as a child inside ConstraintLayout and play with it.

Is there any solid and recommended way to add child views to ConstraintLayout dynamically?

UPDATE: Let me give a not-so-simple example which I what I want to achieve.

Suppose you have a View1, View2 and View3. All V1, V2 and V3 are aligned vertically one below another and are complex views consisting of multiple TextViews and ImageViews. Based on user action and what server sends information, I need to add multiple V1 and V2 (can be 1 pair of V1-V2 and can be 3 pairs of V1-V2)between original V2 and V3. If I am using ConstraintLayout, would it be best if I add multiple constraints programatically when I can easily use LinearLayout with vertical orientation?

Now, in terms of efficiency, performance and less-and-beautiful-code, is ConstraintLayout best for this requirement as compared to Linear Layout?

Tetrachloride answered 25/9, 2018 at 7:20 Comment(3)
You can use ContraintLayout.LayoutParamsContented
Why not add a LinearLayout within your ConstraintLayout, and add child views into it? Maybe put the LinearLayout inside a ScrollView if you want it to be scrollable.Airbrush
@Tetrachloride please check link. This answer might help.Bengal
H
9

Views can be added to ConstraintLayout using addView() in the same way as you would with LinearLayout. The difference is that with ConstraintLayout the added views must be constrained. To constrain a view programmatically, use ConstraintSet.

This class allows you to define programmatically a set of constraints to be used with ConstraintLayout. It lets you create and save constraints, and apply them to an existing ConstraintLayout.

Here is a brief example:

activity_main
Define two TextViews. Center them horizontally and positioned at the top.

<android.support.constraint.ConstraintLayout 
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/topView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Top View"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/bottomView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Bottom View"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/topView" />

</android.support.constraint.ConstraintLayout>

This is what you will see when a new TextView ("Middle View") is added to this layout without setting constraints. Notice that the new view defaults to position (0,0).

enter image description here

Let's say that we want the generated middle view to be placed between the top view and the bottom view centered horizontally in the window like this:

enter image description here

Here is the code that will produce this result:

MainActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Define the new TextView and add it to the ConstraintLayout. Without constraints,
    // this view will be positioned at (0,0).
    TextView middleView = new TextView(this);
    middleView.setId(View.generateViewId());
    middleView.setText("Middle View");
    middleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20.0f);
    ConstraintLayout layout = findViewById(R.id.constraintLayout);
    ConstraintLayout.LayoutParams lp =
        new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,
                                          ConstraintLayout.LayoutParams.WRAP_CONTENT);
    layout.addView(middleView, lp);

    // Move the new view into place by applying constraints.
    ConstraintSet set = new ConstraintSet();
    // Get existing constraints. This will be the base for modification.
    set.clone(layout);
    int topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                                                    16, getResources().getDisplayMetrics());
    // Set up the connections for the new view. Constrain its top to the bottom of the top view.
    set.connect(middleView.getId(), ConstraintSet.TOP, R.id.topView, ConstraintSet.BOTTOM, topMargin);
    // Constrain the top of the bottom view to the bottom of the new view. This will replace
    // the constraint from the bottom view to the bottom of the top view.
    set.connect(R.id.bottomView, ConstraintSet.TOP, middleView.getId(), ConstraintSet.BOTTOM, topMargin);
    // Since views must be constrained vertically and horizontally, establish the horizontal
    // constaints such that the new view is centered.
    set.centerHorizontally(middleView.getId(),ConstraintSet.PARENT_ID);
    // Finally, apply our good work to the layout.
    set.applyTo(layout);
}
Hubsher answered 25/9, 2018 at 15:39 Comment(1)
I did not specify my exact requirements earlier. Please read my updated question.Tetrachloride

© 2022 - 2024 — McMap. All rights reserved.