ConstraintLayout is an Android layout component which allows you to position and size widgets in a flexible way

Overview

ConstraintLayout 🗜️ 📏

core GitHub license

ConstraintLayout is a layout manager for Android which allows you to position and size widgets in a flexible way. It's available for both the Android view system and Jetpack Compose.

This repository contains the core Java engine, Android library, validation tools, and experiments.

Android Reference Docs

Have a question that isn't answered here? Try StackOverflow for ConstraintLayout or MotionLayout.

Using ConstraintLayout

⬇️ Installation

Add the Gradle dependency:

You need to make sure you have the Google repository included in the build.gradle file in the root of your project:

repositories {
    google()
}

Next add a dependency in the build.gradle file of your Gradle module.

If using ConstraintLayout with the Android View system, add:

dependencies {

    implementation("androidx.constraintlayout:constraintlayout:2.1.0")

}

If using ConstraintLayout with Jetpack Compose, add:

dependencies {

    implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02")

}

🎒 🥾 Requirements

  • AndroidX (Your gradle.properties must include android.useAndroidX=true)
  • Min SDK 14+
  • Java 8+

🤩 📱 Key Features

Hello World

">
xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

androidx.constraintlayout.widget.ConstraintLayout>

📐 Aspect Ratio defines one dimension of a widget as a ratio of the other one. If both width and height are set to 0dp the system sets the largest dimensions that satisfy all constraints while maintaining the aspect ratio.

">
<ImageView
    android:id="@+id/image_1"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    tools:src="@tools:sample/avatars" />

⛓️ Chains provide group-like behavior in a single axis (horizontally or vertically). The other axis can be constrained independently.

🦮 Guidelines allow reactive layout behavior with fixed or percentage based positioning for multiple widgets.

">
<androidx.constraintlayout.widget.Guideline
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/guideline"
    app:layout_constraintGuide_begin="100dp"
    android:orientation="vertical"/>

🚧 Barrier references multiple widgets to create a virtual guideline based on the most extreme widget on the specified side.

">
<androidx.constraintlayout.widget.Barrier
    android:id="@+id/barrier"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="start"
    app:constraint_referenced_ids="button1,button2" />

☂️ Group controls the visibility of a set of referenced widgets.

">
<androidx.constraintlayout.widget.Group
    android:id="@+id/group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="visible"
    app:constraint_referenced_ids="button4,button9" />

💫 MotionLayout a subclass of ConstraintLayout that supports transitions between constraint sets defined in MotionScenes. See projects/MotionLayoutExperiments for examples.

🌊 Flow is a VirtualLayout that allows positioning of referenced widgets horizontally or vertically similar to a Chain. If the referenced elements do not fit within the given bounds it has the ability to wrap them and create multiple chains. See projects/CalculatorExperiments for examples.

🌀 CircularFlow is a VirtualLayout that easily organize objects in a circular pattern. See projects/CarouselExperiments for basic examples and projects/MotionLayoutVerification for examples with MotionLayout.

">
<androidx.constraintlayout.helper.widget.CircularFlow
   android:id="@+id/circularFlow"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:circularflow_angles="0,40,80,120"
   app:circularflow_radiusInDP="90,100,110,120"
   app:circularflow_viewCenter="@+id/view1"
   app:constraint_referenced_ids="view2,view3,view4,view5" />

📚 👩‍🏫 Learning Materials

🤝 Contributing

If you'd like to get involved and contribute please read CONTRIBUTING for details on our code of conduct, and the process for submitting pull requests to us.

💻 Authors

  • John Hoford : MotionLayout (jafu888)
  • Nicolas Roard : ConstraintLayout (camaelon)

See also the list of contributors who participated in this project.

🔖 License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details

Comments
  • [OnSwipe] touchAnchor moves faster than cursor / touchRegion ignored after first touch

    [OnSwipe] touchAnchor moves faster than cursor / touchRegion ignored after first touch

    I am experiencing a few bugs in the current MotionLayout,

    • I have set a touchAnchorId (Have the drag act as if it is moving the "touchAnchorSide" of this object), but the AnchorView moves faster than my finger
    • I have set a touchRegionId (Limits the region that the touch can be start in to the bounds of this view (even if the view is invisible)), but after the first touch up, the whole MotionLayout reacts to the swipe
    • WRAP_CONTENT doesn't work for TextViews

    I already tried using app:dragScale="1", but it had no effect. Also, I tried app:motionInterpolator="linear" on the Transition, but it didn't have an effect either.

    This happens on ConstraintLayout version 2.1.0-beta02. The stable version 2.0.4 works fine.

    The MotionScene is quite big. This is the relevant Transition:

        <Transition
            android:id="@+id/transitionDrag"
            app:constraintSetEnd="@id/stateDragEnd"
            app:constraintSetStart="@id/stateDragStart"
            app:motionInterpolator="linear">
    
            <OnSwipe
                app:autoCompleteMode="spring"
                app:dragDirection="dragEnd"
                app:dragScale="1"
                app:dragThreshold="1"
                app:onTouchUp="autoCompleteToStart"
    
                app:springBoundary="bounceStart"
                app:springDamping="40"
                app:springMass="1"
                app:springStiffness="750"
                app:springStopThreshold="5"
    
                app:touchAnchorId="@id/dragHandle"
                app:touchAnchorSide="middle"
                app:touchRegionId="@id/dragHandle" />
        </Transition>
    

    screen-20210524-112237

    Edit: layout_width="wrap_content" doesn't work in this scenario either. ("Quick Buy" should be a single line)

    bug 
    opened by kroegerama 14
  • Running ConstraintLayout live inspector

    Running ConstraintLayout live inspector

    Hi. How do i run ConstrainLayout Link desktop app?

    "run your app and your phone or emulator and the live inspector app on your desktop"

    got constrain layout project opened but how do i build this app

    bug 
    opened by charlee-dev 11
  • Modernize Gradle build

    Modernize Gradle build

    This PR implements a number of improvements in the Gradle build. It's largely a code cleanup, making sure that the build scripts of each project are declarative only. All build logic has been moved in its own subproject.

    It was quite hard to follow what you've done before, but I think I managed to reproduce the previous behavior, in particular with where the artifacts are built (outside of the normal build directories).

    I have migrated everything to the lazy APIs and I also made use of the new Maven Publish plugin. A side effect is that the core project now publishes javadocs and sources. By the way, the javadocs are full of errors which would need to be fixed.

    I don't know how to produce docs for the Android projects, since I'm not an expert, but there was a lot of commented out code in the build that I just removed: for external folks like me it doesn't really make sense to have commented out code: either the code is useful in which case it shouldn't be commented out, but potentially activated by some flags, or it should be removed.

    Here's a build scan after calling dist with this PR: https://scans.gradle.com/s/lst5evsi2rr3k

    And the resulting output directory layout:

    image

    Please make sure to review the generated artifacts as I may have made some mistakes in the transition. I'm happy to answer questions on the new build layout if needed.

    opened by melix 11
  • Upgrade 1.1.3 to 2.0.* fails. AAPT: error: duplicate value for resource

    Upgrade 1.1.3 to 2.0.* fails. AAPT: error: duplicate value for resource

    I am trying to upgrade from 1.1.3 to 2.0.* but keeps getting those errors. Have tried with multiple versions but only 1.1.3 seems to compile. First/main error seems to be this:

    AAPT: error: duplicate value for resource 'attr/defaultState' with config ''

    It relates to this line in values.xml: <declare-styleable name="StateSet"><attr format="reference" name="defaultState"/></declare-styleable>

    > Task :app:mergeDevelopmentResources
    AGPBI: {"kind":"error","text":"Android resource compilation failed","sources":[{"file":"C:\\Users\\xxx\\.gradle\\caches\\transforms-2\\files-2.1\\ac7a3722485ab8c9a6b5e513552ba699\\constraintlayout-2.0.4\\res\\values\\values.xml","position":{"startLine":340,"startColumn":4,"startOffset":35314,"endColumn":105,"endOffset":35415}}],"original":"C:\\Users\\xxx\\.gradle\\caches\\transforms-2\\files-2.1\\ac7a3722485ab8c9a6b5e513552ba699\\constraintlayout-2.0.4\\res\\values\\values.xml:341:5-106: AAPT: error: duplicate value for resource 'attr/defaultState' with config ''.\n    ","tool":"AAPT"}
    AGPBI: {"kind":"error","text":"Android resource compilation failed","sources":[{"file":"C:\\Users\\xxx\\.gradle\\caches\\transforms-2\\files-2.1\\ac7a3722485ab8c9a6b5e513552ba699\\constraintlayout-2.0.4\\res\\values\\values.xml","position":{"startLine":340,"startColumn":4,"startOffset":35314,"endColumn":105,"endOffset":35415}}],"original":"C:\\Users\\xxx\\.gradle\\caches\\transforms-2\\files-2.1\\ac7a3722485ab8c9a6b5e513552ba699\\constraintlayout-2.0.4\\res\\values\\values.xml:341:5-106: AAPT: error: resource previously defined here.\n    ","tool":"AAPT"}
    AGPBI: {"kind":"error","text":"Android resource compilation failed","sources":[{"file":"C:\\Code\\xxx\\app\\build\\intermediates\\incremental\\mergeDevelopmentResources\\merged.dir\\values\\values.xml"}],"original":"C:\\Code\\xxx\\app\\build\\intermediates\\incremental\\mergeDevelopmentResources\\merged.dir\\values\\values.xml: AAPT: error: file failed to compile.\n    ","tool":"AAPT"}
    

    Any one that could see what could cause this issue? It could seem to be some kind of denpendency versions conflict, but still can't get why this would end up in something like this.

    Edit: I found out that the material dependency is part of the problem:

    implementation 'com.google.android.material:material:1.2.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    

    When ever I either upgrade that material to latest version or constraintlayout to 2.0.* it results in the above error, also if both are upgraded. Only with the versions above does it work. How could this be?

    opened by mortenholmgaard 8
  • Carousel helper infinite in MotionLayout by Rodrigo Dominguez

    Carousel helper infinite in MotionLayout by Rodrigo Dominguez

    I add a new attribute to configure the infinite carousel. app:carousel_infinite="true" With this attribute, transition backwardTransition andforwardTransition are enabled always. The iteration of the items is given in the same way as the following sequence: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5].

    Demos

    | Demo name | Normal | Infinite | | ------------- |:-------------:|:-----:| | Demo 010 carousel | | | | Demo 020 carousel | | | | Demo 030 carousel | | | | Demo 040 carousel | | | | Demo 060 carousel | | | | Demo colors carousel | | |

    opened by rodrigomartind 8
  • ConstraintLayout v2.0.2 seems to have rendering bugs

    ConstraintLayout v2.0.2 seems to have rendering bugs

    There is an inconsistent bug in ConstraintLayout 2.0.2 that sometimes completely misrenders UI elements. The problem is described in the thread here: https://kotlinlang.slack.com/archives/C0B8M7BUY/p1602767125009100

    Switching back to 1.1.3 fixed my issues.

    opened by OrhanTozan 8
  • Feature - CircularFlow by Rodrigo Dominguez

    Feature - CircularFlow by Rodrigo Dominguez

    CircularFlow

    I add a class called CircularFlow which allows us to group views with circular references.

    constraint_referenced_ids : It receives id's of the views that will add the references (Eg. "view2, view3, view4,view5,view6").

    circularflow_viewCenter : It receives the id of the view of the center where the views received in constraint_referenced_ids (Eg. "view1")

    circularflow_angles : Receive the angles that you will assign to each view (Eg. "45,90,135,180,225")

    circularflow_radiusInDP : Receive the radios in DP that you will assign to each view (Eg. "90,100,110,120,130")

    How add a view at runtime?

    With method addViewToCircularFlow you can add new views to CircularFlow.

     /**
     * Add a view to the CircularFlow. The referenced view need to be a child of the container parent.
     * The view also need to have its id set in order to be added.
     * The views previous need to have its radius and angle set in order to be added correctly a new view.
     * @param view
     * @param radius
     * @param angle
     * @return
     */
    

    Eg.

    findViewById<View>(R.id.view7).setOnClickListener {
                findViewById<CircularFlow>(R.id.circularFlow).addViewToCircularFlow(
                    it, 140, 200F
                )
            }
    

    Demo add view in emulator

    https://user-images.githubusercontent.com/24611045/107442324-ad3eee80-6b15-11eb-89b5-7f3221f2295d.mp4

    How remove a view at runtime?

    With method removeViewFromCircularFlow you can remove a view from CircularFlow.

     /**
         * Remove a given view from the CircularFlow.
         *
         * @param view
         */
    

    Eg.

    findViewById<View>(R.id.view2).setOnClickListener {
                findViewById<CircularFlow>(R.id.circularFlow).removeViewFromCircularFlow(
                    it
                )
            }
    

    Demo remove view in emulator

    https://user-images.githubusercontent.com/24611045/107656012-80e4b880-6c62-11eb-924f-b0fa1244a2bf.mp4

    Demos in AS:

    https://user-images.githubusercontent.com/24611045/106652697-9aa44280-6574-11eb-819b-cb09f012f748.mov

    https://user-images.githubusercontent.com/24611045/106653120-25853d00-6575-11eb-86ab-dca1a1c85ed9.mov

    opened by rodrigomartind 7
  • MotionLayout with drawer content

    MotionLayout with drawer content

    When I use motion layout in scaffold content, I can't open drawer content with scrolling. If I try to open drawer content, the motion layout will be worked. I know it is working well in XML but I can't find a solution to this problem.

    This is my motion scene: https://gist.github.com/YusufbekIbragimov/aca18bd871468fa0372eb44346a7c6c0 This is my motion file: https://gist.github.com/YusufbekIbragimov/750a766eb3629b2b3b583d6fc58488ed This is mu my main screen file: https://gist.github.com/YusufbekIbragimov/9030b17cc5ccc98aae5a2bd7cda61099

    bug 
    opened by YusufbekIbragimov 6
  • Could you please have a look into this issue

    Could you please have a look into this issue

    As is explained here, i am using a Constraint layout helper to group view, in order to set a11y for view, the things is that starting from Constaintlayout 2.0.2

    Here is the link in Google Issue Tracker but it looks like there is no proiority for it setted. https://issuetracker.google.com/issues/189350496

    bug 
    opened by catluc 6
  • Attribute

    Attribute "android:alpha" has already been defined

    compile with 'androidx.constraintlayout:constraintlayout:2.0.4'

    runs error:

    Attribute "android:alpha" has already been defined Attribute "android:translationX" has already been defined Attribute "android:translationY" has already been defined Attribute "android:translationZ" has already been defined

    bug 
    opened by xuyisheng 6
  • TextView does not resize during transition with MotionLayout

    TextView does not resize during transition with MotionLayout

    If a TextVIew is being resizing during a transition, and the layout_width or layout_height was set to wrap_content, then the widget is not resized well, most of the time the widget flick showing only a part of the component Tested with constraintlayout v2.0.1

    opened by CamiloDelReal 6
  • fix dumping jason add toolsAndroid

    fix dumping jason add toolsAndroid

    This add a toolsAndroid directory for small code tools that people can use to gain insight into ConstraintLayout related stuff. (toolsDesktop to follow) Also updates ConstraintSet JSON writer

    opened by jafu888 1
  • Incorrect JSON syntax produced by ConstraintSet#writeState (WriteJsonEngine)

    Incorrect JSON syntax produced by ConstraintSet#writeState (WriteJsonEngine)

    JSON produced by ConstraintSet$WriteJsonEngine from method ConstraintSet#writeState(0) does not follows RFC 8259 or 4627 standards.

    For example in WriteJsonEngine as key punctuators used single quote but expected double quote.

    bug 
    opened by MairwunNx 1
  • Constraint layout chains are messed

    Constraint layout chains are messed

    I don't know how but the constraint layout's chains are not working with latest version of compose (1.4 -alpha2).

    Here is the code

    private val HeaderArtWorkShape = RoundedCornerShape(20) context(TracksViewModel) @Composable fun Header( modifier: Modifier = Modifier ) { ConstraintLayout(modifier = modifier) {

        val meta by header
        val title = stringResource(value = title)
        val (Artwork, Play, Title, Subtitle, Share, Shuffle, Sort, Divider) = createRefs()
    
        // create the chain
        // this will determine the size of the
        // Header
        constrain(
            ref = createVerticalChain(Artwork, Share, Divider, chainStyle = ChainStyle.Packed),
            constrainBlock = {
                // Divider will act as the center anchor of Play Button
                top.linkTo(parent.top, ContentPadding.normal)
                bottom.linkTo(parent.bottom, ContentPadding.large)
            }
        )
    
        Surface(
            shape = HeaderArtWorkShape,
            elevation = ContentElevation.high,
    
            content = {
                val artwork = meta?.artwork
                Image(data = artwork)
            },
    
            modifier = Modifier
                .constrainAs(Artwork) {
                    start.linkTo(parent.start, ContentPadding.normal)
                    width = Dimension.value(76.dp)
                    height = Dimension.ratio("0.61")
                },
        )
    
        val context = LocalContext.current
        val channel = LocalSnackDataChannel.current
        val enabled by remember { derivedStateOf { selected.size > 0 } }
        //Share
        IconButton(
            onClick = { share(context, channel) },
            imageVector = Icons.TwoTone.Share,
            contentDescription = null,
            enabled = enabled,
            modifier = Modifier
                .padding(top = ContentPadding.large)
                .constrainAs(Share) {}
        )
    
        // Divider
        Divider(
            modifier = Modifier
                .constrainAs(Divider) {}
        )
    
    
        // line 2 is the line of Button aligned with share
        constrain(
            ref = createHorizontalChain(Share, Shuffle, Sort, chainStyle = ChainStyle.Packed(0f)),
            constrainBlock = {
                start.linkTo(Artwork.start)
            }
        )
    
        //Shuffle
        IconButton(
            imageVector = Icons.TwoTone.Shuffle,
            contentDescription = null,
    
            onClick = { onRequestPlay(context, true, channel = channel) },
    
            modifier = Modifier.constrainAs(Shuffle) {
                bottom.linkTo(Share.bottom)
            }
        )
    
        // Sort
        var show by rememberState(initial = false)
        IconButton(
            onClick = { show = true },
    
            modifier = Modifier.constrainAs(Sort) {
                bottom.linkTo(Share.bottom)
            },
    
            content = {
                Icon(imageVector = Icons.TwoTone.Sort, contentDescription = null)
                SortBy(expanded = show) {
                    show = false
                }
            }
        )
    
        // Play Button
        NeumorphicButton(
            shape = CircleShape,
            onClick = { onRequestPlay(context, false, null, channel = channel) },
    
            colors = NeumorphicButtonDefaults.neumorphicButtonColors(
                lightShadowColor = Material.colors.lightShadowColor,
                darkShadowColor = Material.colors.darkShadowColor
            ),
    
            modifier = Modifier
                .constrainAs(Play) {
                    top.linkTo(Divider.top)
                    bottom.linkTo(Divider.bottom)
                    end.linkTo(parent.end, ContentPadding.large)
                    width = Dimension.value(60.dp)
                    height = Dimension.value(60.dp)
                },
    
            content = {
                Icon(
                    painter = painterResource(id = R.drawable.ic_play_arrow),
                    contentDescription = null,
                    modifier = Modifier.requiredSize(20.dp)
                )
            }
        )
    
    
        // Title
        Header(
            text = title,
            style = Material.typography.h5,
            maxLines = 2,
            textAlign = TextAlign.Start,
    
            modifier = Modifier.constrainAs(Title) {
                start.linkTo(Artwork.end, ContentPadding.normal)
                end.linkTo(parent.end, ContentPadding.normal)
                top.linkTo(Artwork.top)
                width = Dimension.fillToConstraints
            }
        )
    
        // Subtitle
        val subtitle = stringResource(value = meta?.subtitle) ?: AnnotatedString("")
        Label(
            text = subtitle,
            textAlign = TextAlign.Start,
            style = Material.typography.caption2,
            fontWeight = FontWeight.SemiBold,
            color = LocalContentColor.current.copy(ContentAlpha.medium),
            maxLines = 2,
            modifier = Modifier
                .constrainAs(Subtitle) {
                    end.linkTo(parent.end, ContentPadding.normal)
                    top.linkTo(Title.bottom)
                    start.linkTo(Title.start)
                    width = Dimension.fillToConstraints
                },
        )
    
        // line 3 of details
        val (Duration, Divider1, Tracks, Divider2, Size) = createRefs()
        constrain(
            ref = createHorizontalChain(
                Duration,
                Divider1,
                Tracks,
                Divider2,
                Size,
                chainStyle = ChainStyle.SpreadInside
            ),
    
            constrainBlock = {
                start.linkTo(Title.start)
                end.linkTo(parent.end, ContentPadding.normal)
            }
        )
    
        //Duration
        val duration = Util.formatAsDuration((meta?.duration ?: 0).toLong())
        Text(
            reference = Duration,
            value = duration,
            title = "Duration",
    
            block = {
                top.linkTo(Subtitle.bottom, ContentPadding.normal)
            }
        )
    
        // Divider 1
        Divider(
            modifier = Modifier.constrainAs(Divider1) {
                top.linkTo(Duration.top, -ContentPadding.small)
                height = Dimension.value(56.dp)
                width = Dimension.value(1.dp)
            }
        )
    
        //Tracks
        val count = meta?.cardinality ?: 0
        Text(
            reference = Tracks,
            value = "$count",
            title = "Tracks",
    
            block = {
                top.linkTo(Duration.top)
            },
        )
    
        //Divider 2
        Divider(
            modifier = Modifier.constrainAs(Divider2) {
                height = Dimension.value(56.dp)
                top.linkTo(Duration.top, -ContentPadding.small)
                width = Dimension.value(1.dp)
            }
        )
    
        // Size
        val size = FileUtils.toFormattedDataUnit(context, meta?.size ?: 0L)
        Text(
            reference = Size,
            value = size,
            title = "Size",
            block = {
                top.linkTo(Duration.top)
            },
        )
    }
    

    }

    Note: The code was working properly in 1.3.0-beta01. Here the chains logic is all messed up.

    bug 
    opened by prime-zs 1
  • Flow views getting clipped

    Flow views getting clipped

    I have a horizontal chain flow of programatically added items (key-value pairs).

            <androidx.constraintlayout.helper.widget.Flow
                android:id="@+id/flow"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:orientation="horizontal"
                app:flow_horizontalAlign="start"
                app:flow_horizontalBias="0"
                app:flow_horizontalGap="8dp"
                app:flow_horizontalStyle="packed"
                app:flow_verticalGap="8dp"
                app:flow_wrapMode="chain"
                app:layout_constraintEnd_toEndOf="@id/endGuideline"
                app:layout_constraintStart_toStartOf="@id/startGuideline"
                app:layout_constraintTop_toBottomOf="@id/title" />
    

    Each item is added with the following layout params:

    ConstraintLayout.LayoutParams(
        ConstraintLayout.LayoutParams.WRAP_CONTENT,
        ConstraintLayout.LayoutParams.WRAP_CONTENT
    ).apply {
        constrainedWidth = true
        constrainedHeight = true
    }
    

    When I add an item with a lot of text, the view is being clipped at the bottom (screenshot 1).

    Everything is working fine if a flow has no horizontal paddings/margins, and horizontally constrained to the parent (Screenshot 2).

    Seems like large views are getting measured wrong.

    Demo project: constraint-layout-issue activity_main.xml item_view.xml MainActivity.kt

    ❌ Screenshot 1 – flow constrained to guidelines (start/end=16dp), large views getting clipped.

    ✅ Screenshot 2 – flow constrained to the parent, everything is fine.

    bug 
    opened by enginegl 3
  • IndexOutOfBoundsException

    IndexOutOfBoundsException

    Fatal Exception: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
           at java.util.ArrayList.get(ArrayList.java:437)
           at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measureChildren(BasicMeasure.java:79)
           at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:278)
           at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:120)
           at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1594)
           at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1708)
           at android.view.View.measure(View.java:27129)
           at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1638)
           at com.baselibrary.view.RtlViewPager.onMeasure(RtlViewPager.java:221)
           at android.view.View.measure(View.java:27129)
           at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
           at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChild(ViewGroup.java:7951)
           at com.baselibrary.view.statelayout.LayoutLevelView.mc(LayoutLevelView.java:105)
           at com.baselibrary.view.statelayout.LayoutLevelView.onMeasure(LayoutLevelView.java:86)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
           at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
           at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
           at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
           at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
           at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
           at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
           at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1277)
           at android.view.View.measure(View.java:27129)
           at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4536)
           at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3228)
           at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3533)
           at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2919)
           at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10491)
           at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1108)
           at android.view.Choreographer.doCallbacks(Choreographer.java:866)
           at android.view.Choreographer.doFrame(Choreographer.java:797)
           at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1092)
           at android.os.Handler.handleCallback(Handler.java:938)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loopOnce(Looper.java:226)
           at android.os.Looper.loop(Looper.java:313)
           at android.app.ActivityThread.main(ActivityThread.java:8663)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
    

    Have not idea if this is the bug of BasicMeasure

    bug 
    opened by CharlieZheng 1
  • Split experiment

    Split experiment

    Experimental Work to understand the flow of Core Helper -> Compose Split is used to split Btn1 and Btn2

    Orientation: 0 -> Horizontal image

    Orientation: 1 -> Vertical image

    opened by jswong65 0
Releases(compose-1.1.0-alpha04)
  • compose-1.1.0-alpha04(Sep 22, 2022)

  • 2.2.0-alpha03(Jul 7, 2022)

    Third alpha release for ConstraintLayout 2.2.0

    Improvement for Grid - https://github.com/androidx/constraintlayout/pull/622 https://github.com/androidx/constraintlayout/pull/626 https://github.com/androidx/constraintlayout/pull/628

    Fix error prone issues - https://github.com/androidx/constraintlayout/pull/629 https://github.com/androidx/constraintlayout/pull/630 https://github.com/androidx/constraintlayout/pull/631

    Improvement for MotionLayout - https://github.com/androidx/constraintlayout/pull/624 https://github.com/androidx/constraintlayout/pull/632

    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-alpha02(Jul 7, 2022)

    Second alpha release for ConstraintLayout 2.2.0

    Include improvements made for the Grid helper - https://github.com/androidx/constraintlayout/pull/612 https://github.com/androidx/constraintlayout/pull/614 https://github.com/androidx/constraintlayout/pull/615 https://github.com/androidx/constraintlayout/pull/618

    add support for no Anchor onSwipe - https://github.com/androidx/constraintlayout/pull/617

    add a standard constraint chain syntax - https://github.com/androidx/constraintlayout/pull/613

    [Compose] Refactor out MotionLayout.kt classes - https://github.com/androidx/constraintlayout/pull/616

    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-alpha01(May 24, 2022)

  • 2.1.4(May 24, 2022)

  • compose-1.0.1(May 24, 2022)

  • compose-1.1.0-alpha01(May 24, 2022)

  • 2.1.3(Jan 14, 2022)

    Point release of the constraintlayout library.

    ConstraintLayout

    • Add getSceneString on ConstraintLayout which gets a json formatted dump of the layout and constraints
    • Add attribute to GuideLine guidelineuseRTL to enable / disable if guideline is using RTL

    ConstraintLayout Compose

    • add support for Margin in barrier id: {type: 'barrier', direction: 'end' , contains: ['id1', 'id2'], margin: -12}
    • add json support for vbias/hbias id: { centerVertically: 'parent', vBias: 0.45 }
    • improve json min/max support width: { value: 'wrap', max: 300, min:20 },
    • mprove chain in dsl val chain1 = createHorizontalChain(box1, box2, chainStyle = ChainStyle.Spread)
    • add DSL for goneMargin , Reset dimensions and transforms
    • add bias centerHorizontallyTo(parent, bias = 0.2f)

    MotionLayout Compose

    • Make Compose MotionLayout @ExperimentalMotionApi
    Source code(tar.gz)
    Source code(zip)
  • compose-1.0.0(Jan 14, 2022)

  • 2.1.2(Nov 22, 2021)

  • compose-1.0.0-rc02(Nov 22, 2021)

  • 2.1.1(Sep 28, 2021)

  • compose-1.0.0-rc01(Sep 28, 2021)

  • compose-1.0.0-beta02(Jul 31, 2021)

  • 2.1.0-rc01(Jul 23, 2021)

  • compose-1.0.0-beta01(Jul 23, 2021)

  • compose-1.0.0-alpha08(Jun 16, 2021)

  • compose-1.0.0-alpha07(Jun 16, 2021)

  • 2.1.0-beta02(May 5, 2021)

    MotionLayout

    A few new features:

    • OnSwipe enhancement including spring (stiffness, damping, mass etc) & never complete
    • jumpToState function
    • ViewTransition downUp mode where on touch Down it plays to 100 and on up reverses to 0

    Various fixes, notably:

    Fix problem in MotionLayout with vertical scroll (#173) Perf improvements on nested MotionLayout (#189) Fast transition with NestedScrollView in MotionLayout (#189) ConstraintSet gone in MotionLayout (#189) Support downUp ViewTransitions in MotionLayout (#190) Fix in ImageFilter when reusing drawables (#192) Add spring support in MotionLayout (#199) Performance improvement to CircularFlow (#200) Fixes in derived constraints / constraint override (#212)

    Source code(tar.gz)
    Source code(zip)
  • compose-1.0.0-alpha06(May 5, 2021)

  • compose-1.0.0-alpha05(Mar 16, 2021)

  • 2.1.0-beta01(Mar 12, 2021)

    ConstraintLayout

    • android:layout_width and android:layout_height are back being non-optional due to compatibility issues.

    Helpers

    • added a way to animate or jump directly to a given item of a Carousel
    • new CircularFlow helper

    MotionLayout

    • Programmatic support for inserting and removing onSwipe and onClick on Transitions
    • Experimental Support for Transitions through screen rotation
    • support duration argument to transitions
    • Better support for customAttributes that are boolean or References
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0-alpha2(Dec 18, 2020)

  • 2.1.0-alpha1(Nov 20, 2020)

Owner
Android Jetpack
Extension libraries for Android
Android Jetpack
Android ConstraintLayout Assessment for kotlin

layouts Android ConstraintsLayout Assessment Initial Figma Design Completed Andr

Max Shemetov 0 Dec 22, 2021
Easy, flexible and powerful Swipe Layout for Android

SwipeRevealLayout A layout that you can swipe/slide to show another layout. Demo Overview Drag mode Drag mode normal: Drag mode same_level: Features F

Chau Thai 1.5k Jan 4, 2023
It's an Android library that allows you to use Layout as RadioButton or CheckBox.

Android - CompoundLayout It's an Android library that allows you to use Layout as RadioButton or CheckBox. The librarie is Android 14+ compatible. Gra

null 483 Nov 25, 2022
GoolgePlusLayout is a custom layout that plays animation on the children views while scrolling as the layout in the Google Plus (android) main page

Google Plus Layout Google Plus Layout is a custom layout that support playing animation on child view(s) in a serialize manner like the the main

Ahmed Nammari 224 Nov 25, 2022
Responsive Layout Gird Configuration using Compose. An adaptive layout

ResponsiveGrid Responsive Grid is most followed layout system by the designer as it adapts to screen size and orientation, ensuring consistency across

null 4 Apr 12, 2022
Added support to modify text size and indicator width based on the original TabLayout.

XTabLayout——可修改选中项字体大小和指示器长度的TabLayout XTabLayout是基于design包中的TabLayout进行了功能的扩展,在保留原有功能的基础上,增加了修改选中项字体大小、修改指示器长度以及限制屏幕显示范围内显示的Tab个数。 集成步骤: 1.添加XTabLayo

Kennor 660 Dec 20, 2022
Android widgets to implement folding animation

FoldableLayout Android widgets to implement folding animation. Sample app Usage Note: minimum Android SDK version is 14. Add dependency to your build.

Alex Vasilkov 1.7k Dec 29, 2022
Android component which presents a dismissible view from the bottom of the screen

BottomSheet BottomSheet is an Android component which presents a dismissible view from the bottom of the screen. BottomSheet can be a useful replaceme

Flipboard 4.5k Dec 28, 2022
An Android Layout which has a same function like https://github.com/romaonthego/RESideMenu

ResideLayout An Android Layout which has a same function like https://github.com/romaonthego/RESideMenu. Can be used on Android 1.6(I haven't try it.)

Yang Hui 392 Oct 12, 2022
Draftsman is an on device layout inspector which can be embedded in your android app.

Draftsman Draftsman is an on-device layout inspector for Android apps. It allows you to view various properties of rendered Android Views such as widt

Gojek 243 Dec 22, 2022
a custom pull-to-refresh layout which contains a interesting animation

This is a project with custom pull-to-refresh layout which contains a interesting animation. And the animation is inspired by https://dribbble.com/sho

ZhangLei 1.8k Dec 27, 2022
Linear Layout Manager which supports WRAP_CONTENT

Linear Layout Manager DEPRECATED RecyclerView supports WRAP_CONTENT starting from Android Support Library 23.2. More details here: http://android-deve

Sergey Solovyev 418 Nov 10, 2022
A 3D Layout for Android,When you use it warp other view,it can became a 3D view,一秒让你的view拥有3D效果!

ThreeDLayout A 3D Layout,When you use it warp other view,it can became a 3D view 中文文档 preview USAGE 1.compile library allprojects { repositories {

androidwing 490 Oct 27, 2022
This library provides a simple way to add a draggable sliding up panel (popularized by Google Music and Google Maps) to your Android application. Brought to you by Umano.

Note: we are not actively responding to issues right now. If you find a bug, please submit a PR. Android Sliding Up Panel This library provides a simp

Umano: News Read To You 9.4k Dec 31, 2022
null 2.4k Dec 30, 2022
VoronoiView is a view (ViewGroup) that allows you to add and display views inside Voronoi diagram regions.

Vorolay VoronoiView is a view (ViewGroup) that allows you to add and display views inside Voronoi diagram regions. [Voronoi diagram] (https://en.wikip

Daniil Jurjev 918 Dec 4, 2022
A library that easily allows you to mask layouts/viewgroups

Maskable Layout Overview ======================= The Maskable Layout is a simple framelayout that allows you to easily mask views and viewgroups. You

Christophe Smet 654 Dec 2, 2022
BlurView - A very fast and dynamic blur layout for Android

BlurView - A very fast and dynamic blur layout for Android

null 16 Jul 11, 2022
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Jan 5, 2023