Removing/Adding constraint programmatically in ConstraintLayout

AndroidAndroid LayoutAndroid ConstraintlayoutAndroid Layoutparams

Android Problem Overview


I want to remove and add constraint programmatically based on some condition. Here are the screenshots:

The button

and I want to remove it like this but in code:

here is button with removed constraint on top

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);

Android Solutions


Solution 1 - Android

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);

Solution 2 - Android

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

Solution 3 - Android

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);

Solution 4 - Android

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
                    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDamir MailybayevView Question on Stackoverflow
Solution 1 - AndroidCheticampView Answer on Stackoverflow
Solution 2 - Androidj2emanueView Answer on Stackoverflow
Solution 3 - AndroidUnmitigatedView Answer on Stackoverflow
Solution 4 - AndroidNarendra_NathView Answer on Stackoverflow