I usually project development essential framework

  1. The most powerful network request Net on Android
  2. The strongest list on Android (including StateLayout) BRV
  3. Android’s most powerful default page StateLayout
  4. JSON and long text log printing tool LogCat
  5. Support for asynchronous and global custom toast tool Tooltip
  6. Develop debug window tool DebugKit
  7. One line of code creates the transparent StatusBar StatusBar

Constraint layout is a layout introduced by Google in AndroidStudio2.2. AndroidStudio 2.3 directly replaces the default layout RelativeLayout created by the Activity. You can see how seriously Google is taking this.

The characteristics of

  1. Work with layout editor to improve efficiency (mouse creates layout, but I still recommend code due to lag /bug/ redundant attributes etc.)
  2. Better screen fit
    1. The percentage
    2. Auxiliary line
    3. Group show hide
    4. Common constraints
    5. Hide state margins
  3. Solve performance problems caused by too many nested layouts (most of the time you only need one root layout because it has the features of other layouts)

This article updates the beta in real time with the latest features

The official documentation

  • ConstraintLayout
  • GitHubPage

Latest dependent version

dependencies {
  compile 'com. Android. Support. The constraint, the constraint - layout: 1.1.1'
}
Copy the code

Layout editor

ConstraintLayout is by far the best layout supported by AndroidStudio’s layout editor.

Layout editor panel

The layout editor has a panel on the left for dragging controls into the layout editor

The control list

On the left side of the layout editor is the full list of controls. You can create a view control by dragging it directly into the layout preview interface. And you don’t need to manually import dependency packages.

Layout editor Settings

Introduction in turn:

  1. Show preview only
  2. Display blueprints only
  3. Both blueprints and previews are displayed
  4. Preview the display direction
  5. Phone Screen Model
  6. System API Version
  7. Preview the interface theme
  8. Previewing the interface language
  9. Layout distortion (that is, to customize a preview layout in detail)

Previews and blueprints

order

ConstraintLayout has the layout editor property, so there is a difference between the preview interface and the actual application. The blueprint mainly shows the layout information clearly

In both cases, you can edit the layout directly to your liking.

Preview interface Control

  1. narrow
  2. Scaling percentage
  3. amplification
  4. To adapt to the screen
  5. Open a thumbnail (you can control the preview screen display range)
  6. Number of errors and warnings

ConstraintLayout Layout property

ConstraintLayout this column is the layout property bar that changes according to the ViewGroup you select. I only introduce ConstraintLayout here. There is nothing else to introduce.

Sequential functions:

  1. Whether to display all constraints (the constraints of your selected controls are displayed regardless of whether they are enabled)
  2. AutoConnect Constraint
  3. Delete all constraints
  4. Infer constraints
  5. The default margins
  6. alignment
  7. arrangement
  8. Auxiliary line (GuideLine)

Automatic connection constraint

This magnet icon if turned on. Control automatically creates a horizontal and a vertical constraint by dragging it into the layout editor.

Reasoning constraint

This is a one-time feature that automatically calculates and imposes one horizontal and one vertical constraint on all unconstrained controls in the current layout editor.

Auxiliary tool

ConstraintLayout can be used with some “helper controls”

GuidLine

The guide user is not visible and has no width or height parameter (even if you set it). It’s just a relative baseline in a constrained layout.

<android.support.constraint.Guideline
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/guideline2"
      android:orientation="vertical"
      app:layout_constraintGuide_percent="0.41"
      />
Copy the code

Guides have three properties

  • Begin The left margin of the relative parent layout
  • End right margin relative to parent layout
  • Percent Indicates the percentage relative to the parent layout
app:layout_constraintGuide_begin="20dp"

app:layout_constraintGuide_end="340dp"

app:layout_constraintGuide_percent="0.055555556"
Copy the code

There are two kinds of guides: horizontal and vertical:

Barriers

Obstacles, divided into vertical and horizontal (similar to GuidLine).

Usage scenario: There is a button on the right side when two texts are side by side, but both texts may be of uncertain length for the package type. Using any text as a constraint on a button can cause the button to overwrite another text. This is where Barriers are needed.

Barrier controls can use properties to constrain multiple controls simultaneously

app:constraint_referenced_ids="tv_1,tv_2"
Copy the code

Then specify the direction in the control through the property

app:barrierDirection="right"
Copy the code

Right and left are equal to vertical

Bottom and top are equal to level

int[]	getReferencedIds()

int	getType(a)

void	setReferencedIds(int[] ids)

void	setType(int type)
Copy the code

Group

Groups are a helper added to Constraintlayout 1.1x to group the Visibility properties of multiple controls simultaneously.

XML attributes

app:constraint_referenced_ids="tv_1,tv_2"
Copy the code

Java method

int[]	getReferencedIds()

void	setReferencedIds(int[] ids)
Copy the code

Through the above properties to fill in the id of multiple controls, you can control multiple controls at the same time to hide and display

Example:

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jiuxing.constraintlayout.MainActivity">

    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="64dp"
        android:layout_marginEnd="60dp"
        android:text="TextView"
        app:layout_constraintBottom_toTopOf="@+id/tv_1"
        app:layout_constraintEnd_toEndOf="parent" />

    <android.support.constraint.Group
        android:id="@+id/group"
        android:layout_width="151dp"
        android:layout_height="126dp"
        android:layout_marginEnd="192dp"
        android:visibility="gone"
        android:layout_marginTop="24dp"
        android:background="@color/colorAccent"
        app:constraint_referenced_ids="tv_1,tv_2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
Copy the code

Tip: Setting the background color does not affect the color of the controls within the Group. Only the Visibility property.

Usage scenarios: In some cases you may need to control multiple controls to be displayed or hidden synchronously, and many views should not be shown to the user unless the data is successfully loaded (layout in load).

Placeholder

Placeholder control; Replace view content by repeatedly setContent;

Example:

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jiuxing.constraintlayout.MainActivity">



    <android.support.constraint.Placeholder
        android:id="@+id/placeholder"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginStart="64dp"
        android:layout_marginTop="48dp"
        app:content="@+id/iv"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:src="@color/colorAccent"
         />

</android.support.constraint.ConstraintLayout>
Copy the code
  • The iv and Placeholder controls both need to set the width and height (or Crash), but the iv size will take effect.
  • The position coordinates are set by the Placeholder, so iv doesn’t have to be set

The power of PlaceHolder is that it also provides code to set the content ID

// Set the content view
View	getContent(a) 
void	setContentId(int id) 
Copy the code

What if the PlaceHolder doesn’t set anything and you want to display it as well

/ / set is empty
void	setEmptyVisibility(int visibility) 
int	getEmptyVisibility(a) 
Copy the code

Example:

Requires it to be set when creating the view, otherwise it will not work (for example, in the onCreate method).

place.setEmptyVisibility(View.VISIBLE);
Copy the code

Circular Position

Three properties are involved

app:layout_constraintCircle="@id/btn_invoke"
<! -- Center control -->
app:layout_constraintCircleRadius="100dp"
<! -- size of circle radius -->
app:layout_constraintCircleAngle="80"
<! -- Angle of the circle -->
Copy the code

Example:

<Button
        android:id="@+id/btn_invoke"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:onClick="invoke"
        android:text="Performing"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        />  

<Button
        android:id="@+id/btn_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="51dp"
        android:layout_marginTop="31dp"
        android:text="2"
        app:layout_constraintCircle="@id/btn_invoke"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintCircleAngle="80"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
Copy the code

Effect:

  1. Using ring positioning causes the previous constraint coordinates to fail
  2. The Angle and radius default to zero, so specifying the circle without setting the Angle and radius will completely overlap

constraint

Before 1.1, if the layout property was WRap_content, the constraint could not be observed. This problem can now be fixed with the following properties;

App: layout_constrainedWidth = "true"Copy the code

Percent Dimensions

ConstraintLayout: When the control is set to 0dp (also called match_constraint), the default behavior is to spread and fill up the available space. However, this behavior can be set using the layout_constraintWidth_default property. In ConstraintLayout 1.0.x, this property can also be set to wrap. At 1.1.x, it has a new value: Percent, allowing us to set the percentage of free space that the control occupies.

The TextView control below will take up 50% of the remaining width and 50% of the remaining height.

    <TextView
        android:id="@+id/textView6"
        android:layout_width="0dp"
        android:layout_height="0dp"
        
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />
Copy the code

The layout properties

In addition to the layout editor writing the layout should also understand the layout properties, otherwise there are some problems you will not see.

Editor properties

This property does not have any effect on Android, only the layout editor coordinates of the AS

tools:layout_editor_absoluteY="246dp"
tools:layout_editor_absoluteX="36dp"
Copy the code

Layout editor

True phone

The constraint

A control has four constraint points/twelve constraint properties (left and right have two properties each start and end and right and left)

Constraints can only be bound to each other at the same level. For example, left and right can be bound, but left cannot be associated with upper and lower constraints.

Constraints are not related relationships. but

// Associate constraints with the parent layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"

// Associate constraints with other controls
app:layout_constraintLeft_toRightOf="@+id/button3"
app:layout_constraintRight_toLeftOf="@+id/button3"
app:layout_constraintTop_toBottomOf="@id/button3"
app:layout_constraintBottom_toTopOf="@id/button3"


layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
Copy the code

Character datum

Some controls contain text, so controls that constrain layout have a text baseline constraint. Default is hidden, need to click the switch to show.

layout_constraintBaseline_toBaselineOf
Copy the code

Note: There is no need to use the upper and lower constraints when using text baseline alignment

Percentage shift

Controls the vertical/horizontal percentage position of the control on the screen by decimal point (percentage).

Note: The control supports percentage offsets only if constraints are added to the horizontal position (upper, lower, left and right constraint points)

app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="0.69"
Copy the code

Note: For ConstraintLayout of a constraint, you can set the percentage offset without these two properties


margin

There’s nothing to say about margins in general. Same as before.

android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
Copy the code

Because the constraint layout controls are so closely related, if a layout is hidden (gone) it can cause the entire layout to move. So ConstraintLayout has a hidden margin property

ConstraintLayout uses the Gone property value

Constraintlayout does not change to 0,0 if the control is hidden. Margin and width are 0.

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
Copy the code

The above margin properties are valid depending on whether the control they constrain is hidden (invisible does not count), while margin is invalid.

Aspect ratio

You can set the aspect ratio of the control by setting the width or constraint to match_constraint(0dp)

The width or height of the matc_constraint is scaled according to the dimensions on the other side

There are two kinds of width and height:

Width:

app:layout_constraintDimensionRatio="2:1"
Copy the code

The default side of match_constraint(0dp) is the aspect ratio.

The constrained will be scaled according to the other side (1:1 ratio for match_constraint and wrap_content will be scaled to square)

The custom

app:layout_constraintDimensionRatio="w,2:1"
Copy the code

I understand that the ratio is reversed. W is set to the ratio of height to width and H to the ratio of width to height. Hands-on experience

Wide high

Width and height attribute value

  • Fixed a Fixed value
  • Wrap_Content parcel value
  • Match_Constraint “0dp”

Match_Constraint

Theoretically, match_parent is no longer used for the width and height of ConstraintLayout. Instead, it is 0DP (called match_constraint).

**Important: **MATCH_PARENT is not supported for widgets contained in a ConstraintLayout, though similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent".

Match_parent is not supported in ConstraintLayout

Match_constraint is only valid if it has a constraint in both directions, horizontal or vertical, matching all remaining space. If there is only one horizontal or no constraint is equivalent to WRAP_content.

Figure:

The editor automatically converts it to a fixed DP value if you force it, but it’s fine if you just constrain ConstraintLayout. Can’t understand what I’m saying about try it yourself.

Chain mode

When two Spaces are constrained to each other, a chain is created.

This can only be done by selecting multiple centers or by direct XML editing.

app:layout_constraintHorizontal_chainStyle="packed"
Copy the code

Links together can be set to different styles to match the width or height of the parent container. Note: a chain and the first control need to be styled (chainStyle).

There are three parameter values based on the style:

  • Spread uniform (default style)
  • Head and tail to the side, other middle evenly Spread inside
  • Be Packed with people

There is an official brochure

Although it looks like there are five, the properties are actually the same three. But there are weights and percentage offsets added. Bias is the deviation, and weighted is the weight.

The weight

Same as the Wight property of the LinearLayout. However, only spread and Spread_inside are supported.

layout_constraintHorizontal_weight
Copy the code

You can also edit properties and modify them with the mouse

Wide high constraint

Wrap_content is not restricted by constraints (this issue was resolved in ConstraintLayout1.1)

App: layout_constrainedWidth = "true | false" app: layout_constrainedHeight true | = "false"Copy the code

Optimizer

Keep in mind that ConstraintLayout will have to measure the control twice when we use MATCH_CONSTRAINT, and the operation of measuring is expensive.

ConstraintLayout ¶ The Optimizer optimizes ConstraintLayout with the following property for ConstraintLauyout:

  • Layout_optimizationLevel.

The possible values are:

  • None: the optimization is not applied.
  • Standard: Only direct and barrier constraints (default) are optimized.
  • Direct: Optimizes the direct constraint.
  • Barrier: Optimizes barrier constraints.
  • Chain: Optimize chain constraints (experiment).
  • Dimensions: Optimized size measurement (experiment).

When setting the value, you can set multiple values, such as:

app:layout_optimizationLevel="direct|barrier|dimensions"
Copy the code

ConstraintSet

Modify ConstraintLayout officials do not recommend using ConstraintLayout. LayoutParams ConstraintSet but recommended

ConstraintSet allows you to create or change constraints/margins directly in code, and both provide methods instead of member variables.

If you want to modify the properties of any of the ConstraintLayout controls, you need to do the following three steps.

Steps:

  1. Clone or load the XMl layout
  2. Modify the properties
  3. Apply to the new layout

Example:

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.state1);
        Context context = this;
        
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
        mConstraintSet.clone(mConstraintLayout); // Clone a layout to ConstraintSet
    }

    public void onClick(View view) {
        TransitionManager.beginDelayedTransition(mConstraintLayout); // Add a line of code to the animation
        mConstraintSet1.applyTo(mConstraintLayout); // Apply to the new layout}}Copy the code

The official example, but I found I was invalid.

cloning

Copy a ConstraintLayout to ConstraintSet. You can then modify ConstraintSet (that is, the layout of the copy).

void clone (ConstraintSet set)

void clone (ConstraintLayout constraintLayout)

void clone (Context context, 
                int constraintLayoutId)
Copy the code

Create a constraint

This simply means creating a constraint. A control can have n constraints. At least two to determine the location.

It is important to note that START and LEFT themselves can coexist. Don’t mix

void connect(int startID, int startSide, int endID, int endSide)

void connect(int startID, int startSide, int endID, int endSide, int margin)
Copy the code

Example:

// Clone the layout
mConstraintSet = new ConstraintSet();
mConstraintSet.clone(mBinding.root); 


// Connect two controls with three constraints
mConstraintSet.connect(R.id.btn_3, ConstraintSet.LEFT, R.id.btn, ConstraintSet.RIGHT, 100);
mConstraintSet.connect(R.id.btn_3, ConstraintSet.TOP, R.id.btn, ConstraintSet.TOP);
mConstraintSet.connect(R.id.btn_3, ConstraintSet.BOTTOM, R.id.btn, ConstraintSet.BOTTOM);

// Apply the layout
mConstraintSet.applyTo(mBinding.root);
Copy the code

Vertical center

void	centerVertically(int viewId, int toView)

void	centerVertically(int centerID, 
                         int topId,  
                         int topSide,  
                         int topMargin,
                         int bottomId, 
                         int bottomSide, 
                         int bottomMargin,
                         float bias)
Copy the code

Example: Vertical center relative to parent layout

mConstraintSet.centerVertically(R.id.btn_3, ConstraintSet.PARENT_ID);
Copy the code

Vertical center relative to other controls

mConstraintSet.centerVertically(R.id.btn_3, R.id.btn);
Copy the code

Error: If you use a property like TOP or BOTTOM, it will only stick to the TOP.. It’s not centered

mConstraintSet.centerVertically(R.id.btn_3, ConstraintSet.TOP);
Copy the code

Note that if you use LEFT or RIGHT vertically centered in the second method it will cause the program to stop

Horizontal center

You cannot use TOP or BOTTOM for horizontal center, and there is a difference between Rtl and no Rtl

void	centerHorizontally(int centerID, 
                           int leftId, 
                           int leftSide, 
                           int leftMargin, 
                           int rightId, 
                           int rightSide, 
                           int rightMargin,
                           float bias)

void	centerHorizontally(int viewId, 
                           int toView)
// Crash can only be used if LEFT/RIGHT no

void	centerHorizontallyRtl(int viewId,
                              int toView)


void	centerHorizontallyRtl(int centerID, 
                              int startId, 
                              int startSide, 
                              int startMargin, 
                              int endId, 
                              int endSide, 
                              int endMargin, 
                              float bias)
// Use only START/END
Copy the code

Example:

// Center the parent layout
mConstraintSet.centerHorizontallyRtl(R.id.btn_3, ConstraintSet.PARENT_ID);

mConstraintSet.centerHorizontallyRtl(R.id.btn_3, R.id.btn, ConstraintSet.START, 0, R.id.btn_2, ConstraintSet.END, 0.0.5 f);
Copy the code

In the middle

This method supports not only horizontal center but also vertical center.

void center (int centerID, 
                int firstID, 
                int firstSide, 
                int firstMargin, 
                int secondId, 
                int secondSide, 
                int secondMargin, 
                float bias)
Copy the code

Wide high

It can be a pixel value size or WRAP_CONTENT or MATCH_CONSTRAINT

void constrainHeight (int viewId, 
                int height) // Pixel units

void constrainWidth (int viewId, 
                int width)
Copy the code

The maximum and minimum width and height are only valid in the MATCH_CONSTRAINT case

void constrainMaxHeight (int viewId, 
                int height)


void constrainMinHeight (int viewId, 
                int height)



void constrainMaxWidth (int viewId, 
                int width)

void constrainMinWidth (int viewId, 
                int width)
Copy the code

Default width and height: the width of a uniform arrangement (e.g., weight mode)

void constrainDefaultWidth (int viewId, 
                int width)

void constrainDefaultWidth (int viewId, 
                int width)
Copy the code

GuidLine

To create a Guideline

void create (intGuidelineID, // Specifies the id of the guideline createdint orientation) / / guidline direction
Copy the code

Set the Guideline margins

void setGuidelineEnd (int guidelineID, 
                int margin)

void setGuidelineBegin (int guidelineID, 
                int margin)

void setGuidelinePercent (int guidelineID, 
                float ratio)
Copy the code

Barrier

void createBarrier (int id,  // id
                intDirection, / / directionint. referenced) / / group id
Copy the code

Set the type

void setBarrierType (int id, 
                int type)
Copy the code

Remove the constraint

void clear (int viewId, 
                int anchor)
// Delete a constraint on this space

void clear (int viewId)
// Remove all constraints from the control
Copy the code

Example: Remove the top constraint

mConstraintSet.clear(R.id.btn, ConstraintSet.TOP);
Copy the code

transparency

void setAlpha (int viewId, 
                float alpha)
Copy the code

rotating

The center of rotation is the center of the control

void setRotation (int viewId, 
                float rotation)
// Rotate around the upper left corner of the control

void setRotationX (int viewId, 
                float rotationX)

// Flip by the x axis of the control

void setRotationY (int viewId, 
                float rotationY)
// Turn the control by its Y-axis
Copy the code

The zoom

Control-centric, percentage floating point

void setScaleX (int viewId, 
                float scaleX) // Multiples

void setScaleY (int viewId, 
                float scaleY)
Copy the code

The offset

Offset to the center of the control

void setTranslation (int viewId, 
                float translationX, 
                float translationY)

void setTranslationX (int viewId, 
                float translationX)

void setTranslationY (int viewId, 
                float translationY)

void setTranslationZ (int viewId, 
                float translationZ)
// The z-offset must be greater than 21 to be valid
Copy the code

Set the margins

void setMargin (int viewId, 
                int anchor, 
                int value)
Copy the code

Example:

mConstraintSet.setMargin(R.id.btn, ConstraintSet.TOP, 200);
Copy the code

The percentage

You must set both constraints (such as left and right or up and down) if you want the percentage to work

void setHorizontalBias (int viewId, 
                float bias)

void setVerticalBias (int viewId, 
                float bias)
Copy the code

application

Applies the ConstraintLayout of Clone from the current ConstraintSet instance to a ConstraintLayout. Since you created ConstraintSet using the Clone () method, not using apply() will not change the ConstraintLayout of Clone.

void applyTo (ConstraintLayout constraintLayout)
Copy the code

Load the XML

Load an XML layout file without Clone.

void load (Context context, 
                int resourceId)
Copy the code

Issues

It mainly introduces some problems which may be bugs or my knowledge level is not enough

The tools named

If you use the infer Constraint you will find that many tools-beginning properties are automatically generated. These properties are left alone and have no effect on the application.

tools:layout_constraintTop_creator="1"
Copy the code

Control cannot be dragged

This is mainly because the control has two left and right margin properties (start and left or right and end)

Delete start or end. I think it is a bug and have submitted it to Google.(My recommendation is to use START and END all the time)

Mutual constraints in the layout editor

The two controls must bind each other to use the Chain, but they cannot bind each other in the layout editor

However, XML direct editing or the following methods can be constrained each other, so I think it is a bug

Controls disappear

If it appears that the control is not displayed in the editor, check the editor property coordinates.

tools:layout_editor_absoluteX="137dp"
tools:layout_editor_absoluteY="-118dp"
Copy the code