Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add Dynamic child views vertically to ConstraintLayout

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?

like image 942
Nike15 Avatar asked Sep 25 '18 07:09

Nike15


People also ask

How do you add vertical constraints?

Click Guidelines in the toolbar, and then click Add Vertical Barrier or Add Horizontal Barrier. In the Component Tree window, select the views you want inside the barrier and drag them into the barrier component. Select the barrier from the Component Tree, open the Attributes window, and then set the barrierDirection.

Can we use linear layout in ConstraintLayout?

You can create linear layouts now with ConstraintLayout by constraining the sides of each element with each other. The quick way of creating these layouts is to select all the views together and right click to center horizontally or vertically.

Which is better RelativeLayout or ConstraintLayout?

If you have the choice start with ConstraintLayout, but if you already have your app in RelativeLayout, stay with it. That's all I have been following. RelativeLayout is very limited in functionality and many complex layouts can't be made using it, especially when ratios are involved.

Is ConstraintLayout faster than LinearLayout?

More complex layout but results are the same, flat Constraint Layout is slower than nested Linear Layout. I want to pay attention to 2 more things which are more subjective. Creating Constraint Layout takes more time than other layouts. Also introducing changes in existing Constraint Layout is much more time-consuming.


1 Answers

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);
}
like image 90
Cheticamp Avatar answered Sep 22 '22 12:09

Cheticamp