{"id":19442591,"url":"https://github.com/ackeecz/anko-constraint-layout","last_synced_at":"2025-04-25T00:32:01.453Z","repository":{"id":52507961,"uuid":"107263461","full_name":"AckeeCZ/anko-constraint-layout","owner":"AckeeCZ","description":"DSL implementation of constraint layout for anko","archived":false,"fork":false,"pushed_at":"2021-04-27T07:55:53.000Z","size":521,"stargazers_count":38,"open_issues_count":1,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-15T00:06:19.506Z","etag":null,"topics":["android","anko","constraint-layout"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AckeeCZ.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-17T12:08:44.000Z","updated_at":"2023-02-04T00:20:00.000Z","dependencies_parsed_at":"2022-09-06T13:11:47.146Z","dependency_job_id":null,"html_url":"https://github.com/AckeeCZ/anko-constraint-layout","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AckeeCZ%2Fanko-constraint-layout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AckeeCZ%2Fanko-constraint-layout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AckeeCZ%2Fanko-constraint-layout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AckeeCZ%2Fanko-constraint-layout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AckeeCZ","download_url":"https://codeload.github.com/AckeeCZ/anko-constraint-layout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223975012,"owners_count":17234735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","anko","constraint-layout"],"created_at":"2024-11-10T15:40:04.209Z","updated_at":"2024-11-10T15:40:04.723Z","avatar_url":"https://github.com/AckeeCZ.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[ ![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.ackeecz/anko-constraint-layout/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.ackeecz/anko-constraint-layout)\n# Anko Constraint Layout\n\nThis library adds missing support for Constraint Layout in Anko library. It is \nbased on the `1.1.3` version of the library and supports `Group`, `Barrier`\nand `Placeholder` views as well.\n\n## Usage\n\nConstraint Layout is defined and added to other ViewGroups in the same way as any other view in Anko:\n```kotlin\nanyViewGroupLayout {\n    constraintLayout {\n        val name = textView(\"David\")\n        val surname = textView(\"Khol\")\n    \n        constraints {\n            name.connect(\n                    STARTS of parentId with 16.dp,\n                    TOPS of parentId with 16.dp\n            )\n            surname.connect(\n                    TOP to BOTTOM of name,\n                    STARTS of name\n            )\n        }\n    }.lparams(matchParent, matchParent)\n}\n```\nor it can be also created through `ViewManager`, `Context`, `Activity` as usual.\n\n## Views positioning and ConstraintSet\n\nTo correctly position all views inside the Constraint Layout, we can set layout params to each child\nit contains just as if we were using traditional xml definitions.\n\nWhen defining layout programmatically, another approach is preferred. Instead of specifying layout\nparams for each child, we can specify relations between children through a `ConstraintSet`.\n`ConstraintSet` adds extra helper methods to define constraints more expressively and intuitively.\n\nYou can create, define constraints into and then apply a Constraint Set to a Constraint Layout \nusing `constraints` block:\n\n```kotlin\nconstraintLayout {\n    // view definitions\n    \n    constraints {\n        // view constraint definitions\n    }\n}\n```\n\nInside of the `constraints` block we can use various methods to define our layout:\n \n### Connect\n\nThe most common thing to do with Constraint Layout is defining constraints. You can define a constraint\nusing `View.connect()` method.\n\n```kotlin\nconstraints {\n    name.connect(\n            STARTS of parentId with 16.dp,\n            TOPS of parentId with 16.dp\n    )\n    surname.connect(\n            TOP to BOTTOM of name,\n            STARTS of name\n    )\n    avatar.connect(\n            HORIZONTAL of name,\n            TOP to BOTTOM of name with 8.dp\n    )\n}\n```\n\n`View.connect()` method accepts variable amount of constraints. Each constraint is defined like this:\n\n```SIDE to SIDE of VIEW [with MARGIN]``` \n* First `SIDE` defines side of the view we create constraints for. \n* Second `SIDE` defines side of the view we connect first view to.\n* `VIEW` defines the view we connect first view to\n* `with MARGIN` clause is optional and defines margin from the first view to the second one\n\nAvailable `SIDE`s are: `LEFT`, `RIGHT`, `TOP`, `BOTTOM`, `BASELINE`, `START`, `END`\n \nTo reduce boilerplate, instead of `START to START` you can just specify `STARTS` etc.\nAdditionally you can use `HORIZONTAL` to define `LEFTS` and `RIGHTS` at the same time and \nanalogously `VERTICAL` to define `TOPS` and `BOTTOMS`.\nMoreover, you can use `ALL` to define constraints for all four sides at the same time. \n\n### Chains\nYou can define [chains](https://developer.android.com/training/constraint-layout/index.html#constrain-chain)\nwith `chain()`, `chainSpread()`, `chainSpreadInside()` or `chainPacked()` methods like this: \n\n```kotlin\nconstraints {\n    val views = arrayOf(name, surname) \n    views.chainSpread(TOP of parentId, BOTTOM of parentId)\n}\n```\nYou have to define at least 2 elements of the chain. When either `chain spread` or \n`chain spread inside` is used, you can also pass weights parameter to mimic functionality \nof `LinearLayout` and it's weights. To make weights work, you also have to set the \nview's height or width to `matchConstraint` (0dp).\n\nFor more information about chains, have a look at [this great article](https://medium.com/@nomanr/constraintlayout-chains-4f3b58ea15bb) by Noman Rafique.\n\n### Dimensions and Ratios\nYou can define view's width and height with `width()` and `height()` or `size()` methods.\nMoreover you can define an [dimension ratio](https://developer.android.com/training/constraint-layout/index.html#ratio) \n(also refered to as aspect ratio) for any view with `dimensionRatio()` method. To make aspect \nratio work you must set at least one of height and width to `matchConstraint`.\n\n```kotlin\nconstraints {\n    image.size(matchConstraint, matchConstraint)\n    image.dimensionRatio(\"H,16:9\")\n}                \n```\n\n### Guidelines\nYou can create [guidelines](https://developer.android.com/reference/android/support/constraint/Guideline.html) \nin two ways - either as a standalone `View`:\n```kotlin\nconstraintLayout {\n    val topGuide: Guideline = horizontalGuidelineBegin(dip(24))\n}\n```\nor as a part of Constraint Set:\n```kotlin\nconstraints {\n    val leftGuideId: Int = verticalGuidelineBegin(dip(72))\n}\n```\nUltimately, it is up to you which one you want to use as you can make references to either of those \ninside of `connect()` method.\n ```kotlin\nconstraintLayout {\n    val name = textView(\"David\")\n    val topGuide: Guideline = horizontalGuidelineBegin(dip(24))\n    \n    constraints {\n        val leftGuideId: Int = verticalGuidelineBegin(dip(72))\n        name.connect(\n                STARTS of leftGuideId,\n                TOP of topGuide\n        )\n    }\n}\n```\nAll six combinations of helper methods (`HORIZONTAL | VERTICAL` combined with \n`BEGIN | END | PERCENT`) are available.\n\n### Barriers\nSimilarly to guidelines, you can also define barriers either as a standalone `View`:\n```kotlin\nconstraintLayout {\n    val descriptionBarrier: Barrier = barrierLeft(name, surname)\n}\n```\nor as a part of Constraint Set:\n```kotlin\nconstraints {\n    val descriptionBarrier: Int = barrierLeft(name, surname)\n}\n```\nUltimately, the use inside of `connect()` method does not differ:\n```kotlin\nconstraints {\n    // ...\n    description.connect(\n            ENDS of descriptionBarrier,\n            TOPS of parentId\n    )\n}\n```\n\n### Groups\nYou can define a group of views and control its visibility and elevation (and possibly more with\nfuture updates to the Constraint Layout library) for all referenced views.\n```kotlin\nconstraintLayout {\n    val buttonsGroup = group(buttonOne, buttonTwo)\n    \n    constraints {\n        buttonsGroup.visibility(View.GONE)\n    }\n}\n```\n\n\u003e Additionally for both `Barrier` and `Group` you can easily add to and remove from \nreferenced views with `addViews(vararg View)` and `removeViews(vararg View)` respectively.\n\n\n### Biases\nIf you constrain a view from both sides horizontally or vertically, you can also define \n[bias](https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#Bias).\n```kotlin\nconstraints {\n    avatar.connect(\n        HORIZONTAL of parentId,\n        TOP of parentId\n    )\n    avatar.horizontalBias(0.2f)\n}\n```\nAnother option how to define the bias is to use `View.center()` function which also\naccepts a bias parameter:\n```kotlin\nconstraints {\n    avatar.center(START of background, START of name, 0.2f)\n}\n```\n\n### Placeholders\nYou can define a [placeholder](http://androidkt.com/constraintlayout/#80f0) and dynamically \nreplace the contents of the placeholder with `placeholder.setContent(View)` method:\n```kotlin\nconstraintLayout {\n    val placeholder = placeholder()\n    \n    button(\"Click me\") {\n        setOnClickListener {\n            placeholder.setContent(this@button)\n        }\n    }\n    \n    constraints {\n        button.connect(/* add connections */)\n        placeholder.connect(/* add connections */)\n    }\n}\n```\n\nWhen you set a view as a content of the placeholder, the view will be displayed with \nlayout params of the placeholder. When you set another view as a content of the placeholder\n(or pass null as the content view), the original view will return to its original \nposition and size. \n\n### Percent dimensions, constrained dimensions\nSee [official docs](https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#DimensionConstraints)\nfor more information.\n\nPrior to version 1.1.0-beta 5 it was not possible to define these dimensions through Constraint Set. \nTo use them, you had to define attributes directly in the view's layout params.\n```kotlin\nconstraintLayout {\n    button().lparams {\n        constrainedWidth = true\n    \n        matchConstraintDefaultWidth = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT\n        matchConstraintPercentWidth = 0.8f\n    }\n}\n```\n\nNow you can set percent dimensions to the Constraint Set.\n```kotlin\nconstraints {\n    button.width(matchConstraint)\n    button.percentWidth(0.8f)\n}\n```\n\n\n\n### Circular positioning\nWith version 1.1.0-beta 5 you can now set circular positioning through Constrain Set as well.\n```kotlin\nconstraintLayout {\n    val centerView = view()\n    \n    constraints {\n        button.circle(centerView, 32.dp, 45f)\n    }\n}\n```\n\n\n## IDs\nConstraint Layout heavily depends on ids of its child views. \nFor that reason, each child has to have defined a unique id.\nWe can predefine static ids for each view in `ids.xml` file to be generated by aapt and reference\nthem in code by `R.id.name_of_view_id`. This can be burdensome to do for every view we add.\n\nThis library automatically generates a **dynamic** unique id for each view that is added to the \nConstraint Layout and does not have a specified id.\nThis ensures positioning of views works correctly, but these ids do NOT get retained across \nconfiguration changes. That means any view that save its state into a bundle to be persisted across\nconfiguration change will NOT be able to restore its state.\nFor numerous views such as `TextView`, `Button`, `ImageView`, etc. it is not a big deal because these\nviews usually don't modify their state based on user input. For other views such as `EditText`, \n`CheckBox`, `RadioButton`, `SeekBar`, etc. it is strongly advised to specify a static id so that\nAndroid framework can restore the view's state automatically.\n\nIf you want to disable this functionality, you may set generateIds to false.\n```kotlin\nval view = context.constraintLayout {\n\n    generateIds = false\n    // added views here won't have generated ids\n                 \n    generateIds = true\n    // added views here will once again have generated ids, unless an id has been assigned during their creation\n}\n```\n\n\u003e Do NOT change ids of views after they have been added to the ConstraintLayout. ConstrainLayout\ninternally stores references to its views via views' id when they have been added. Changing view's id\nand referencing it through its new id will not work and the view will most likely not even get displayed.\n\n## Managing multiple Constraint Sets\nYou can define and switch between multiple Constraint Sets by simply using `constraints` block \nmultiple times and storing returned values.\n\nYou can also use `prepareConstraints` block to define relations between views, but not apply it \nto the Constraint Layout. This might be useful when you define multiple constraint sets and \ndon't want the changes from the first constraint set to be propagated to other ones.\n```kotlin\nconstraintLayout {\n    val collapsedConstraintSet = prepareConstraints {\n        // set of constraints\n    }\n    \n    val expandedConstraintSet = constraints {\n        // another set of constraints\n    }\n}\n```\nThen during runtime you can easily switch between different layouts without recreating the layout.\n```kotlin\nif (isActivated) {\n    expandedConstraintSet\n} else {\n    collapsedConstraintSet\n}.applyTo(this@constraintLayout)\n```\n\n## Chaining calls\nYou can also chain calls like this:\n```kotlin\nbackground\n        .width(matchConstraint)\n        .connect(HORIZONTAL of parentId)\n        .connect(TOPS of parentId)\n        .dimensionRatio(\"H,1:1\")\n```\n\n## Sample\nSample app can be found in `app` module.\n\n## Dependencies\nAdd this dependency to your project:\n```groovy\nimplementation 'io.github.ackeecz:anko-constraint-layout:2.0.0'\n```\nThis library is based on the `1.1.3` version of support library so make sure you add appropriate\ndependency.\n```groovy\nimplementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n```\n\n## References\nFor more information about Constraint Layout in general, check out these websites:\n * https://constraintlayout.com/\n * https://developer.android.com/training/constraint-layout/index.html\n * https://academy.realm.io/posts/360-andev-2017-nicolas-roard-advanced-constraintlayout/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fackeecz%2Fanko-constraint-layout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fackeecz%2Fanko-constraint-layout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fackeecz%2Fanko-constraint-layout/lists"}