Programmatically add constraints to View in constraint layout - android

I'm creating TextViews programmatically and adding them to my constraint layout. They are by default placed in the top left corner. I want them to go below each other, the first one being below an EditText.
This is my code:
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.cLayout);
ConstraintSet set = new ConstraintSet();
TextView tv = new TextView(this);
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT, // Width of TextView
ConstraintLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lp);
set.clone(layout);
set.connect(tv.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 8);
set.connect(tv.getId(), ConstraintSet.TOP, editText.getId(), ConstraintSet.BOTTOM, 8);
tv.setId(View.generateViewId());
set.applyTo(layout);
layout.addView(tv,0);
As you see, I've already set a constraint from TOP of View to BOTTOM of editText. Still, it shows in the top left corner. Why is that?

Your code order isn't proper, the following code should work.
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.cLayout);
TextView tv = new TextView(this);
tv.setText("Something");
tv.setId(View.generateViewId());
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT, // Width of TextView
ConstraintLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lp);
layout.addView(tv,0);
ConstraintSet set = new ConstraintSet();
set.clone(layout);
set.connect(tv.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 8);
set.connect(tv.getId(), ConstraintSet.TOP, editText.getId(), ConstraintSet.BOTTOM, 8);
set.applyTo(layout);
P.S - I agree with Syed Ahmed Jamil that you should preferably use a RecyclerView or ListView, but it doesn't hurt to know how to set ConstraintLayout constraints properly.

Related

How do I add views dynamically through Kotlin code

So I need to add views to my constraint layout for each item in a list.
The code I have right now is:
for (i in 0..hikes.size - 1) {
var parentLayout = findViewById<ConstraintLayout>(R.id.RoutesOverview)
var constraintSet = ConstraintSet()
var view = View(this)
view.id = i
var params = ConstraintLayout.LayoutParams (
LayoutParams.MATCH_PARENT,
700
)
params.setMargins(48, 48, 48, 0)
view.setBackgroundColor(Color.parseColor("#81c27a"))
view.layoutParams = params
RoutesOverview.addView(view)
constraintSet.clone(parentLayout)
constraintSet.connect(view.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
constraintSet.connect(view.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
constraintSet.connect(view.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
constraintSet.connect(view.id, ConstraintSet.TOP, prev.id, ConstraintSet.TOP)
constraintSet.applyTo(parentLayout)
prev = view
}
The RoutesOverview object is just the constraintLayout from my xml.
In the first iteration the prev object contains a view who is always there.
When trying this code, I see that the left and right margin gets set correctly, but the top doesn't nor get the second, third... view placed correctly.
The purpose of the views is actually just to use as a background for other textviews to get displayed on, I don't know if there's a better way to do this.

How to use ConstraintSet to set what like app:layout_constraintBottom_toBottomOf?

Now,here is my question.
how can I use ConstraintSet's connect to set attr like 'app:layout_constraintBottom_toBottomOf="parent"'
Try this
TextView textView = new TextView(this);
textView.setId(R.id.text_id);
ConstraintSet set = new ConstraintSet();
set.clone(constraintLayout);
set.connect(textView.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0);
constraintLayout.addView(textView);
set.applyTo(constraintLayout);

Adding constraints to views programmatically using ConstraintSet does not give expected result in Android?

I have a custom ConstraintLayout, and there's a TextView inside of it. I'm doing everything programmatically WITHOUT XML at all, here's the code:
public class CustomView extends ConstraintLayout {
private TextView textView;
public CustomView(Context context) {
super(context);
textView = new TextView(context);
textView.setId(View.generateViewId());
textView.setText("...");
// Adding border to the view in order to visualize the frame
GradientDrawable border = new GradientDrawable();
border.setColor(Color.TRANSPARENT);
border.setStroke(1, Color.BLACK);
textView.setBackground(border);
addView(textView);
// Apply constraints to textView. Left = right = top = bottom = 120
ConstraintSet set = new ConstraintSet();
set.clone(this);
set.connect(textView.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 120);
set.connect(textView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 120);
set.connect(textView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 120);
set.connect(textView.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 120);
set.applyTo(this);
}
}
When I run the above code, I'm getting some wrong results:
If the text in textView is short:
If the text in textView is long:
If I understand correct that your wrong result - you don't see the margins?
I think this because defaults layout_width layout_height of your textview - wrap_content. Defaults must be 0dp.
Try like:
LayoutParams lp = new LayoutParams(0, 0);
textView.setLayoutParams(lp);

Can't see my programmatically added textviews in ConstraintLayout

I've added 2 textviews in ConstrainLayout in code, but i can't see them.
The screen is empty.
Please can anybody help me to figure out this?
Thanks a lot!
public class ActivitySixth extends AppCompatActivity {
private TextView tv1;
private TextView tv3;
private ConstraintLayout mConstraintLayout;
private static final int ID_CONS_LAY = 160;
private static final int ID_TV1 = 160;
private static final int ID_TV3 = 160;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sixth);
mConstraintLayout = findViewById(R.id.parent_Constraint);
ConstraintSet set = new ConstraintSet();
set.clone(mConstraintLayout);
tv1 = new TextView(this);
tv3 = new TextView(this);
tv1.setText("TextView number ONE");
tv3.setText("TextView number THREE");
tv1.setId(ID_TV1);
tv3.setId(ID_TV3);
mConstraintLayout.addView(tv1);
mConstraintLayout.addView(tv3);
set.connect(tv1.getId(), ConstraintSet.LEFT, R.id.parent_Constraint, ConstraintSet.LEFT, 0);
set.connect(tv3.getId(), ConstraintSet.RIGHT, R.id.parent_Constraint, ConstraintSet.RIGHT, 0);
set.applyTo(mConstraintLayout);
}
}
First, the IDs should be different, second, you need to add constraints to the TextViews' width/height:
set.connect(tv1.getId(), ConstraintSet.LEFT, R.id.parent_Constraint, ConstraintSet.LEFT, 0);
set.constrainWidth(tv1.getId(), WRAP_CONTENT);
set.constrainHeight(tv1.getId(), WRAP_CONTENT);
set.connect(tv3.getId(), ConstraintSet.RIGHT, R.id.parent_Constraint, ConstraintSet.RIGHT, 0);
set.constrainWidth(tv3.getId(), WRAP_CONTENT);
set.constrainHeight(tv3.getId(), WRAP_CONTENT);
set.applyTo(mConstraintLayout);
By the way, to avoid conflicts, you can define ids using resources xml.
create ids.xml inside your res\values folder
define ids:
<resources>
<item type="id" name="textView1" />
</resources>
use the defined id:
R.id.textView1
Hello Please follow below code
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.mainConstraint);
ConstraintSet set = new ConstraintSet();
ImageView view = new ImageView(this);
layout.addView(view, 0);
set.clone(layout);
set.connect(view.getId(), ConstraintSet.TOP, layout.getId(), ConstraintSet.TOP, 60);
set.applyTo(layout);
TextView contactUs = new TextView(this);
contactUs.setText(R.string.contactus);
contactUs.setTextSize(25);
contactUs.setId(R.id.contactUs);
ConstraintLayout.LayoutParams clpcontactUs = new ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
contactUs.setLayoutParams(clpcontactUs);
constraintLayout.addView(contactUs);
ConstraintSet set = new ConstraintSet();
set.clone(mConstraintLayout);
set.connect(tv1.getId(), ConstraintSet.LEFT, R.id.parent_Constraint, ConstraintSet.LEFT, 0);
set.connect(tv3.getId(), ConstraintSet.RIGHT, R.id.parent_Constraint, ConstraintSet.RIGHT, 0);
set.applyTo(mConstraintLayout);
try something like this..
ref. http://www.zoftino.com/adding-views-&-constraints-to-android-constraint-layout-programmatically

Set ConstraintLayout width to match parent width programmatically

In an android application I am attempting to programmatically add customized ConstraintLayout views to a vertically oriented LinearLayout.
I set the LayoutParams to MATCH_PARENT for width and WRAP_CONTENT for height in the ConstraintLayouts. However, when I run the application the ConstraintView is all scrunched up and the content is overlapping. Below are some relevant snippets and a screenshot of my application. How do I go about correcting this issue?
public class ItemView extends ConstraintLayout {
LinearLayout linearButtons;
LinearLayout linearText;
public ItemView(Context context, String name, String price, ArrayList<String> guests,
ArrayList<String> checked, int id) {
...
addView(linearText);
addView(linearButtons);
set.clone(this);
set.connect(linearText.getId(), ConstraintSet.LEFT, this.getId(),
ConstraintSet.LEFT, 8);
set.connect(linearText.getId(), ConstraintSet.TOP, this.getId(),
ConstraintSet.TOP, 8);
set.connect(linearButtons.getId(), ConstraintSet.RIGHT, this.getId(),
ConstraintSet.RIGHT, 8);
set.connect(linearButtons.getId(), ConstraintSet.TOP, this.getId(),
ConstraintSet.TOP, 8);
}
elsewhere:
for (Item it:r.getItems()) {
ItemView itemView = new ItemView(this, it.getName(), nf.format(it.getPrice()), dinerlist, it.getGuests(), i);
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.MATCH_PARENT);
itemView.setLayoutParams(params);
vg.addV[enter image description here][1]iew(itemView);
Log.d("ItemView Children: ", itemView.getWidth()+" "+itemView.getHeight());
In ConstraintLayout in xml when you want a "MATCH_PARENT" width, you have to set the width to 0dp and then set the layout_constraintWidth_default attribute to "spread"
Programmatically you can do the same:
a) set a 0 dp width and height
b) set defaultWidth and defaultHeight constraints
//add the view with 0dp width and height
val layoutParams = ConstraintLayout.LayoutParams(0, 0)
val view = View(context)
view.layoutParams = layoutParams
view.id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) View.generateViewId() else R.id.yourLayoutId
parent.addView(view)
//apply the default width and height constraints in code
val constraints = ConstraintSet()
constraints.clone(parent)
constraints.constrainDefaultHeight(view.id, ConstraintSet.MATCH_CONSTRAINT_SPREAD)
constraints.constrainDefaultWidth(view.id, ConstraintSet.MATCH_CONSTRAINT_SPREAD)
constraints.applyTo(parent)
If you need Java:
//add the view with 0dp width and height
ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(0, 0);
View view = View(context);
view.setLayoutParams(layoutParams);
view.setId(R.id.yourLayoutId);
parent.addView(view);
//apply the default width and height constraints in code
ConstraintSet constraints = new ConstraintSet();
constraints.clone(parent);
constraints.constrainDefaultHeight(view.getId(), ConstraintSet.MATCH_CONSTRAINT_SPREAD);
constraints.constrainDefaultWidth(view.getId(), ConstraintSet.MATCH_CONSTRAINT_SPREAD);
constraints.applyTo(parent);

Categories

Resources