How to access parent in ConstraintLayout - android

I am using ConstraintLayout to create a view programmatically and I want to set my button view topTotop of parent and leftToleft of the parent. How can I do that?
My code is below:
Button button = new Button(MainActivity.this);
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(widthInt, heightInt);
params.topToTop = // I want to set it parent
params.leftToLeft = // I want to set it parent
params.setMargins(marginStartint , marginTopInt , 0 , 0);
button.setLayoutParams(params);

You can use PARENT_ID
so your code becomes
params.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
params.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;

You can use ConstraintSet's Connect method to perform such operations. There PARENT_ID to refer parent id.
ConstraintLayout layout = (ConstraintLayout)fndViewById(R.id.mainConstraint);
ConstraintSet set = new ConstraintSet();
set.clone(layout);
set.connect(view.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0);
//view refers to the view's constraint to be changed
set.applyTo(layout);
connect
void connect (int startID,
int startSide,
int endID,
int endSide,
int margin)
Create a constraint between two widgets.

Related

How to add a plain text view with the pressing of a button in android?

What I want to learn is,
When the button is clicked, a new plain text(editable) should appear below the default plain text I have created in the UI with the same properties as the default one(for example, same width, height) with some margin in between each one.
My project layout type is constraint layout, I wanted my buttons to be placed in the bottom right corner of the UI and I had archived that with the constraint one.
By browsing through stack Overflow and others through google,
All I saw is about adding plain text in a linear layout, if i switched from constraint layout to linear layout, my buttons get misplaced and not that I had at least implemented the functionality to add plain text with a click of the button with the linear layout.
that's why I am sticking to the constraint layout with this at least my buttons don't get misplaced, if there is any way in any layout can get me the result I want, I am open to it.
So far I done this
ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout);
Button buttonAddNewToDo = findViewById(R.id.addNewToDo);
buttonAddNewToDo.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
EditText newToDo = new EditText(MainActivity.this);
newToDo.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
newToDo.setHint("enter new to do");
constraintLayout.addView(newToDo);
}
});
the code is within the onCreate() FYI.
What the above code does is, when the button is clicked, it creates a new plain text, it's in the top left corner,
To see the UI for the above piece of code(see the image below)
enter image description here
Constraint layout needs extra information other than just adding a view to the layout, that where to attach the view in the layout.
EditText newToDo = new EditText(MainActivity.this);
newToDo.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
newToDo.setHint("enter new to do");
constraintLayout.addView(newToDo);
After adding this view to the layout, set constraints for this view. For adding view directly below default Text view, we need the id of that Text View and after that all other subsequent views which we'll generate dynamically.
int lastEditTextId = 0;
boolean isFirstEditText = true;
ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout);
Button buttonAddNewToDo = findViewById(R.id.addNewToDo);
buttonAddNewToDo.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
EditText newToDo = new EditText(MainActivity.this);
newToDo.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
newToDo.setHint("enter new to do");
constraintLayout.addView(newToDo);
newToDo.setId(View.generateViewId());
//Setting constraint set for the new view
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(
newToDo.getId(),
ConstraintSet.START,
ConstraintSet.PARENT_ID,
ConstraintSet.START
);
constraintSet.connect(
newToDo.getId(),
ConstraintSet.END,
ConstraintSet.PARENT_ID,
ConstraintSet.END
);
if (isFirstEditText) {
constraintSet.connect(
newToDo.getId(),
ConstraintSet.TOP,
YOUR_DEFAULT_TEXT_VIEW.getId(),
ConstraintSet.BOTTOM
);
isFirstEditText = false;
} else {
constraintSet.connect(
newToDo.getId(),
ConstraintSet.TOP,
lastEditTextId,
ConstraintSet.BOTTOM
);
}
lastEditTextId = newToDo.getId();
constraintSet.applyTo(constraintLayout);
});
You can design the edit text in the xml file with initial visibility gone. When button in clicked the set the visibility visible.
xml
<EditText
android:visibility = "gone" />
Activity
buttonAddNewToDo.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
edittext.setvisibility(View.Visible);
}
});

Adding constraints programmatically

What is the translation to java code of the following XML instructions used in a layout definition with a constraint layout?
app:layout_constraintBottom_toBottomOf="#+id/Button1"
app:layout_constraintTop_toTopOf="#+id/Button1"
app:layout_constraintLeft_toLeftOf="#+id/Button2"
app:layout_constraintRight_toRightOf="Button2"
Here is an example of adding constraints programatically,
ConstraintLayout mConstraintLayout = (ConstraintLayout)fndViewById(R.id.mainConstraint);
ConstraintSet set = new ConstraintSet();
ImageView view = new ImageView(this);
mConstraintLayout.addView(view,0);
set.clone(mConstraintLayout);
set.connect(view.getId(), ConstraintSet.TOP, mConstraintLayout.getId(), ConstraintSet.TOP, 60);
set.applyTo(mConstraintLayout);
To know more details you can refer Constraint layout

Removing/Adding constraint programmatically in ConstraintLayout

I want to remove and add constraint programmatically based on some condition. Here are the screenshots:
and I want to remove it like this but in code:
so the same effect in want to achieve programmatically
and here is the code that I tried:
if (advertisements.size() > 0) { //my own condition
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) btnCreateAd.getLayoutParams();
layoutParams.topToBottom = R.id.imvEmpty; //the imageview that is in center of the view
btnCreateAd.setLayoutParams(layoutParams);
recyclerView.setVisibility(View.VISIBLE);
txvMyAdEmptyText.setVisibility(View.GONE);
imvEmpty.setVisibility(View.GONE);
adapter.setList(advertisements);
adapter.notifyDataSetChanged();
} else {
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) btnCreateAd.getLayoutParams();
layoutParams.topToBottom = -1; //here i am trying to remove top constraint but it doesn't work
btnCreateAd.setLayoutParams(layoutParams);
recyclerView.setVisibility(View.GONE);
txvMyAdEmptyText.setVisibility(View.VISIBLE);
imvEmpty.setVisibility(View.VISIBLE);
adapter.setList(new ArrayList<Advertisement>());
}
mConstraintView.invalidate(); //this is my constraint view
EDIT
I have tried using ConstraintSet also, but the result was even different somehow my RecyclerView (which is set to boundaries of parent view) was disappearing
ConstraintSet set = new ConstraintSet();
set.clone(parentView);
if (advertisements.size() > 0) {
recyclerView.setVisibility(View.VISIBLE);
txvMyAdEmptyText.setVisibility(View.GONE);
imvEmpty.setVisibility(View.GONE);
adapter.setList(advertisements);
adapter.notifyDataSetChanged();
} else {
set.connect(btnCreateAd.getId(), ConstraintSet.TOP, imvEmpty.getId(), ConstraintSet.BOTTOM, 0);
recyclerView.setVisibility(View.GONE);
txvMyAdEmptyText.setVisibility(View.VISIBLE);
imvEmpty.setVisibility(View.VISIBLE);
adapter.setList(new ArrayList<Advertisement>());
}
set.connect(btnCreateAd.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);
set.connect(btnCreateAd.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0);
set.connect(btnCreateAd.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0);
set.applyTo(parentView);
I have not worked through your code, but the following illustrates how to break and make the constraint using ConstraintSet.
ConstraintSet set = new ConstraintSet();
ConstraintLayout layout;
layout = (ConstraintLayout) findViewById(R.id.layout);
set.clone(layout);
// The following breaks the connection.
set.clear(R.id.bottomText, ConstraintSet.TOP);
// Comment out line above and uncomment line below to make the connection.
// set.connect(R.id.bottomText, ConstraintSet.TOP, R.id.imageView, ConstraintSet.BOTTOM, 0);
set.applyTo(layout);
Another way of doing this is with ConstraintLayout.LayoutParams.UNSET. This way is not using ConstraintSet.clear.
Assuming we want to remove the bottom constraint of our constraintLayout itself but can be any view:
val containerParams = cl_container.layoutParams as ConstraintLayout.LayoutParams
containerParams.bottomToBottom = ConstraintLayout.LayoutParams.UNSET
cl_container.layoutParams = containerParams
Here is the Java version of the answer from j2emanue using ConstraintLayout.LayoutParams, which works without specifying the id of the element that the layout is contrained to:
final ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout);
final ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) constraintLayout.getLayoutParams();
layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.UNSET;
constraintLayout.setLayoutParams(layoutParams);
There is an easier way to do it now if you're using viewBinding/dataBinding with Kotlin.
There is an extension function called updateLayoutParams from import androidx.core.view.updateLayoutParams and use it like below
binding.yourView.updateLayoutParams<ConstraintLayout.LayoutParams> {
this.startToEnd = ConstraintLayout.LayoutParams.UNSET
this.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
}

Add a view programmatically in ConstraintLayout

I try to add a View at the same place of an other View in a ConstraintLayout but the added View don't get the LayoutParams of the other View.
The added View take place on the top|left of the container.
This is my code :
TextView cloneView = new TextView(getContext());
cloneView.setLayoutParams(otherView.getLayoutParams());
mainContainer.addView(cloneView);
To add views to a ConstraintLayout you have to add the constraints using a ConstraintSet.
View v = findViewById(...);
ConstraintLayout cl = (ConstraintLayout) findViewById(...);
ConstraintSet c = new ConstraintSet();
cl.addView(v);
int id = v.getId();
c.clone(cl);
c.connect(id, ConstraintSet.Top, otherViewIdAboveV, ConstraintSet.BOTTOM, 0);
...
other constraints
...
c.applyTo(cl);

Android : How to programmatically set layout_constraintRight_toRightOf "parent"

I have a view in ConstrainLayout as follows.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="260dp"
android:textColor="#FFF"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="#+id/parent"
app:layout_constraintTop_toBottomOf="#id/message_date"
android:id="#+id/text_main"
/>
I would like to change the view to either app:layout_constraintLeft_toLeftOf="#+id/parent" or layout_constraintLeft_toRightOf="#+id/parent" programmatically in recycleViewHolder based on some conditions.
Here is an example of setting a button to the bottom of parent view using java code:
ConstraintLayout constraintLayout;
ConstraintSet constraintSet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constraintLayout = (ConstraintLayout) findViewById(R.id.activity_main_constraint_layout);
Button button = new Button(this);
button.setText("Hello");
constraintLayout.addView(button);
constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(button.getId(), ConstraintSet.LEFT, constraintLayout.getId(), ConstraintSet.RIGHT, 0);
constraintSet.constrainDefaultHeight(button.getId(), 200);
constraintSet.applyTo(constraintLayout);
}
to achieve something like this,
app:layout_constraintLeft_toLeftOf="#+id/parent"
your java code should look like this
set.connect(YOURVIEW.getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT,0);
and to achieve something like this,
layout_constraintLeft_toRightOf="#+id/parent"
your java code should look like this,
set.connect(YOURVIEW.getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT,0);
Here, I'm assuming android:id="#+id/parent" is the id of your parent ConstraintLayout .
constraintSet = new ConstraintSet(); and so on
Did not work for me anyhow.
Solved by
LayoutParams layoutParams = (LayoutParams) viewToChange.getLayoutParams();
layoutParams.leftToLeft = anotherViewId;
layoutParams.rightToRight =anotherViewId;
layoutParams.topToTop = anotherViewId;
layoutParams.bottomToBottom = anotherViewId;
layoutParams.startToStart =anotherViewId;
layoutParams.endToEnd = anotherViewId;
viewToChange.setLayoutParams(layoutParams);
Use id
class MyLayout(context: Context) : ConstraintLayout(context) {
fun show() {
val view = ImageView(context)
addView(view)
val params = view.layoutParams as ConstraintLayout.LayoutParams
params.height = 100
params.width = 50
params.rightToRight = id
view.requestLayout()
}
}
I had same situation when I needed to move buttons down once a new EditText appears, In XML file they had constraints like this:
app:layout_constraintTop_toBottomOf="#+id/first_layout"
and what I needed to do is changing to sth like programmatically:
app:layout_constraintTop_toBottomOf="#+id/second_layout"
Using ConstraintLayout.LayoutParams the task is pretty straightforward e.g.
Kotlin:
val currentLayout = btn.layoutParams as ConstraintLayout.LayoutParams // btn is a View here
currentLayout.topToBottom = R.id.second_layout // resource ID of new parent field
btn.layoutParams = currentLayout
and that's it!
Haven't seen better solution than this:
textMain.updateLayoutParams<ConstraintLayout.LayoutParams> {
startToEnd = anyOtherView.id
topToTop = anyOtherView.id
endToStart = anyOtherView.id
bottomToBottom = anyOtherView.id
}
In Android, you can programmatically set the layout_constraintRight_toRightOf attribute to "parent" using the ConstraintLayout.LayoutParams class. Here's an example:
ConstraintLayout layout = findViewById(R.id.constraint_layout);
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) view.getLayoutParams();
params.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID;
view.setLayoutParams(params);
In the above example, "constraint_layout" is the id of the ConstraintLayout, "view" is the view that you want to set the constraint on and the "params.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID" is used to set the layout_constraintRight_toRightOf attribute to "parent".
This will set the right side of the view to the right side of its parent, aligning it to the right edge of the screen.
You can also use setRightToRight(int rightToRight) method of ConstraintLayout.LayoutParams.
It's also important to note that you should call requestLayout() on the view after modifying its layout parameters, so that the changes will be reflected on the layout.

Categories

Resources