Reputation: 544
Android ViewGroup
has the following methods to add (child) Views:
I know we can easily define horizontal/vertical orientation to LinearLayout in xml/programatically and add child views, eg.
Similarly with RelativeLayout, we can use ViewGroup
's addView
and RelativeLayout.LayoutParams
's method:
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 View
1, View
2 and View
3. All V1, V2 and V3 are aligned vertically one below another and are complex views consisting of multiple TextView
s and ImageView
s. 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?
Upvotes: 6
Views: 5045
Reputation: 62831
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).
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:
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);
}
Upvotes: 9