I have set up a new project in android studio. Compatibility Android 9 Java.
I want to add multible 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);
}
}
CodePudding user response:
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);
}