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
Related
I have been using constraintlayout animations using two layout files
private void animate() {
ConstraintSet set1 = new ConstraintSet();
set1.clone(root);
ConstraintSet set2 = new ConstraintSet();
set2.clone(this, R.layout.layout_file_2);
TransitionManager.beginDelayedTransition(root, transition);
set2.applyTo(root);
}
However, in the layout i am only changing two constraints. I decided to try doing so programmatically and did this, which worked.
private void showHidden() {
ConstraintLayout parentLayout = findViewById(R.id.root_constraint_layout);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(parentLayout);
constraintSet.connect(R.id.search_layout, ConstraintSet.TOP, R.id.toolbar_layout, ConstraintSet.BOTTOM);
constraintSet.connect(R.id.search_layout, ConstraintSet.BOTTOM, R.id.root_constraint_layout, ConstraintSet.BOTTOM);
constraintSet.applyTo(parentLayout);
}
This is however, not animated. I tried to animate as I did before in the first one (using only 1 layout file this time) and my result was this
private void animate2() {
ConstraintLayout parentLayout = findViewById(R.id.root_constraint_layout);
ConstraintSet set1 = new ConstraintSet();
set1.clone(parentLayout);
ConstraintSet set2 = new ConstraintSet();
set2.clone(parentLayout);
set2.connect(R.id.search_layout, ConstraintSet.TOP, R.id.toolbar_layout, ConstraintSet.BOTTOM);
set2.connect(R.id.search_layout, ConstraintSet.BOTTOM, R.id.root_constraint_layout, ConstraintSet.BOTTOM);
Transition transition = new Slide(Gravity.END).setDuration(500);
TransitionManager.beginDelayedTransition(parentLayout, transition);
set2.applyTo(parentLayout);
}
This works like the second one, but shows no animation, the new constraints immediately jump into place. Is there any way I can make the animation work without using two layoyuts? or is there something i'm doing wrong? thanks.
You didn't clear the constraints on side of view on which you applying constraint set .
You can do this approach using
constraintSet.clear(view.Layout.id, ConstraintSet.LEFT) //You can change LEFT with whatever side you are choosing
Before connecting layout sides using connect function .
Here is the full code for getting it in better way :-
val constraintSet = ConstraintSet()
constraintSet.clone(view.rootLayout)
view.layout.animate().alpha(1f).duration = 700
constraintSet.clear(view.layout.id, ConstraintSet.LEFT)
constraintSet.connect(
view.layout.id,
ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID,
ConstraintSet.RIGHT
)
view.layout.animate().translationX(resources.getDimension(R.dimen.zeroDP))
val transition: Transition = ChangeBounds()
transition.interpolator = EasingInterpolator(Ease.QUINT_OUT)
transition.duration = 700
TransitionManager.beginDelayedTransition(view.rootLayout, transition)
constraintSet.applyTo(view.rootLayout)
I am trying to change the constraints programmatically as follows:
final ConstraintSet set = new ConstraintSet();
set.clone(this);
if(text == null) {
view.setVisibility(GONE);
set.clear(div.getId(), ConstraintSet.TOP);
set.connect(div.getId(), ConstraintSet.TOP, otherView.getId(), ConstraintSet.BOTTOM);
}
set.applyTo(this);
But the rule is not applied. The div goes to the top of the layout like there is no top constraint.
What am I doing wrong?
Update
If I change the following:
set.clone(this);
...
set.apply(this);
to:
View root = LayoutInflater.from(getContext()).inflate(R.layout.my_layout, this);
ConstraintLayout layout = root.findViewById(R.id.constraint_layout);
....
set.clone(layout);
....
set.apply(layout);
The layout is correct! But I don't understand why.
this is a ConstraintLayout since I am extending a 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
}
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.
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);