How to programmatically access the current constraints of views in a ConstraintLayout?
Asked Answered
N

1

10

I can programmatically modify constraints of a view in a ConstraintLayout using ConstraintSet but before applying modifications, I want to test that it hasn't been done already. To do this I need to programmatically access the current constraints of a view in a ConstraintLayout.

For example, here I want to remove the constraint between the top of the TextView 'title' and the bottom of TextView view 'subtitle'. Then Constrain the top of TextView 'title' to the bottom of 'videoView'. But first I need to check if TextView 'title' isn't already constrained to the bottom of 'videoView' (code modified from android's official website). Note, I can't insert the final line of HTML on this website, it's /android.support.constraint.ConstraintLayout in angle brackets.

public class MainActivity extends AppCompatActivity {
ConstraintSet mConstraintSet = new ConstraintSet(); // create a Constraint Set
ConstraintLayout mConstraintLayout; // cache the ConstraintLayout

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mConstraintLayout = (ConstraintLayout) findViewById(R.id.root);
    mConstraintSet.clone(mConstraintLayout); // get constraints from ConstraintSet
}

public void userDoesSomething(View v) {
    //test if title has already been constrained to bottom of videoView
    if (mConstraintLayout 'TITLE' IS NOT CONSTRAINED TO THE BOTTOM OF 'VIDEOVIEW'){
        mConstraintSet.connect(R.id.Title, ConstraintSet.TOP, R.id.videoView, ConstraintSet.BOTTOM); // set new constraints to ConstraintSet
        mConstraintSet.applyTo(mConstraintLayout); // set new constraints to ConstraintLayout
    }
}

}

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.test.MainActivity"
android:orientation="vertical">

<VideoView
    android:id="@+id/videoView"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"

    />

<TextView
    android:id="@+id/subtitiles"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/videoView"
    app:layout_constraintLeft_toLeftOf="parent"
    android:gravity="center"
    android:text="The problem with this pond is that there are too many toads"
    android:textSize="25sp"
    android:background="@android:color/white"

    />

<TextView
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/subtitiles"
    app:layout_constraintLeft_toLeftOf="parent"
    android:gravity="center"
    android:text="Toad"
    android:textSize="25sp"
    android:background="@android:color/white"
    />

Nonessential answered 18/8, 2017 at 14:40 Comment(7)
Is not really clear what you are askingGamboa
@rakwaht. The view @+id/title is constrained to the view @+id/subtitiles. I want to be able to access this information from my MainActivity in the similar way that I can access the height using view.getHeight(). Is it possible?Nonessential
Just look at the Official Docs, they even have an example. developer.android.com/reference/android/support/constraint/…Spilt
@Martin Marconcini. I used this same link to write the example in my question. I don't see where it shows me how to find out what the constraints of a view are. For example (as I said in the above comment), you can see that in my layout @+id/title is constrained to the view @+id/subtitiles. I want to be able to access this information from my MainActivity in the similar way that I can access the height using view.getHeight().Nonessential
It does perfectly show you how to do it, because by cloning a ConstrainSet and, by extension, by obtaining the layout params of any widget, you have access to all its information, including, but not limited to what you’re looking for, which is the topToBottom value, according to the accepted answer. You asked "need to programmatically access the current constraints of a view in a ConstraintLayout”. You clone or get the layout params, you cast them to the right type, and you have access to its values.Spilt
@Martin Marconcini. Thanks for the clarification! Sorry don't have enough reputation to upvote it. Being quite new, ConstraintLayout lacks easy to understand explanations for beginners on forums like this one. So I'm sure your answer will be helpful for others like myself.Nonessential
No worries, I didn’t mean to sound like an as****e, apologies. I agree it’s too new and therefore hard to grasp sometimes. Even “seasoned” Android Developers struggle to understand the concept of “constraints”. It took me a while on OS X/iOS to grasp AutoLayout, so when coming to CL, I found it a lot easier to assimilate, due to the similarities between both. Good luck!Spilt
Z
9

To my acknowledge, there isn't method for that, hovewer you can try to comparate two ConstraintLayout.LayoutParams, for exemple :

public class MainActivity extends AppCompatActivity {
ConstraintSet mConstraintSet = new ConstraintSet(); // create a Constraint Set
ConstraintLayout mConstraintLayout; // cache the ConstraintLayout

int mConstraintValue;
TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.root);
        mTextView = (TextView) findViewById(R.id.title);
        mConstraintSet.clone(mConstraintLayout); // get constraints from ConstraintSet
        ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mTextView.getLayoutParams();
        mConstraintValue = params.topToBottom;
    }

    public void userDoesSomething(View v) {
        //test if title has already been constrained to bottom of videoView
         ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mTextView.getLayoutParams();
        if (mConstraintValue.equals(params.topToBottom)){
            mConstraintSet.connect(R.id.Title, ConstraintSet.TOP, R.id.videoView, ConstraintSet.BOTTOM); // set new constraints to ConstraintSet
            mConstraintSet.applyTo(mConstraintLayout); // set new constraints to ConstraintLayout
        }
    }
}

Hope this helps.

Zitazitah answered 18/8, 2017 at 16:3 Comment(1)
Thanks so much! Calling topToBottom from the ConstraintLayout.LayoutParams of a view tells me the ID of the view which is constrained to the top of it. Documentation hereNonessential

© 2022 - 2024 — McMap. All rights reserved.