{"id":13428307,"url":"https://github.com/skydoves/TransformationLayout","last_synced_at":"2025-03-16T01:32:34.163Z","repository":{"id":40758321,"uuid":"243753387","full_name":"skydoves/TransformationLayout","owner":"skydoves","description":"🌠 Transform between two Views, Activities, and Fragments, or a View to a Fragment with container transform animations for Android.","archived":false,"fork":false,"pushed_at":"2024-06-25T12:59:52.000Z","size":38837,"stargazers_count":2361,"open_issues_count":7,"forks_count":192,"subscribers_count":23,"default_branch":"main","last_synced_at":"2024-10-22T16:16:44.971Z","etag":null,"topics":["android","android-library","android-ui","kotlin","material","motions","skydoves","transition"],"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/skydoves.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"skydoves","custom":["https://www.paypal.me/skydoves","https://www.buymeacoffee.com/skydoves"]}},"created_at":"2020-02-28T12:05:07.000Z","updated_at":"2024-10-22T06:26:55.000Z","dependencies_parsed_at":"2024-06-25T14:17:31.374Z","dependency_job_id":"66db42e7-b6f1-416c-a554-144bf3484ba6","html_url":"https://github.com/skydoves/TransformationLayout","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skydoves%2FTransformationLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skydoves%2FTransformationLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skydoves%2FTransformationLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skydoves%2FTransformationLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skydoves","download_url":"https://codeload.github.com/skydoves/TransformationLayout/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221631917,"owners_count":16855021,"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","android-library","android-ui","kotlin","material","motions","skydoves","transition"],"created_at":"2024-07-31T01:00:51.842Z","updated_at":"2025-03-16T01:32:34.156Z","avatar_url":"https://github.com/skydoves.png","language":"Kotlin","readme":"\u003ch1 align=\"center\"\u003eTransformationLayout\u003c/h1\u003e\u003c/br\u003e\n\u003cp align=\"center\"\u003e \n🌠 Transform views, activity, and fragments into other components with container transform animations.\n\u003c/p\u003e\n\u003c/br\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://devlibrary.withgoogle.com/products/android/repos/skydoves-TransformationLayout\"\u003e\u003cimg alt=\"Google\" src=\"https://skydoves.github.io/badges/google-devlib.svg\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://android-arsenal.com/api?level=21\"\u003e\u003cimg alt=\"API\" src=\"https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/skydoves/TransformationLayout/actions\"\u003e\u003cimg alt=\"Build Status\" src=\"https://github.com/skydoves/TransformationLayout/workflows/Android%20CI/badge.svg\"/\u003e\u003c/a\u003e \n  \u003ca href=\"https://github.com/skydoves\"\u003e\u003cimg alt=\"Profile\" src=\"https://skydoves.github.io/badges/skydoves.svg\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Download\nGo to the [Releases](https://github.com/skydoves/TransformationLayout/releases) to download the demo APK.\n\n## Screenshots\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"/preview/preview0.gif\" width=\"270\"/\u003e\n\u003cimg src=\"/preview/preview1.gif\" width=\"270\"/\u003e\n\u003cimg src=\"/preview/preview2.gif\" width=\"270\"/\u003e\n\u003c/p\u003e\n\n## Morphing Animation for Jetpack Compose\nIf you want to implement morphing animation in Jetpack Compose, check out [Orbital](https://github.com/skydoves/Orbital).\n\n## Including in your project\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.skydoves/transformationlayout.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.skydoves%22%20AND%20a:%22transformationlayout%22)\n\n### Gradle\nAdd the dependency below to your **module**'s `build.gradle` file:\n\n```gradle\ndependencies {\n    implementation(\"com.github.skydoves:transformationlayout:1.1.5\")\n}\n```\n\n## Usage\nAdd the XML namespace below inside your XML layout file:\n\n```gradle\nxmlns:app=\"http://schemas.android.com/apk/res-auto\"\n```\n\n### TransformationLayout\n`TransformationLayout` is an essential concept to transform your Views, Activities, and Fragments into other components. You must wrap one or more Views that are supposed to be transformed using `TransformationLayout` like the example code below:\n\n```gradle\n\u003ccom.skydoves.transformationlayout.TransformationLayout\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"wrap_content\"\n  app:transformation_targetView=\"@+id/my_cardView\" // sets a target view.\n  app:transformation_duration=\"450\" // sets a duration of the transformation.\n  app:transformation_direction=\"auto\" // auto, entering, returning\n  app:transformation_fadeMode=\"in\" // in, out, cross, through\n  app:transformation_fitMode=\"auto\" // auto, height, width\n  app:transformation_pathMode=\"arc\" // arc, linear\n\u003e\n\n   \u003c!-- other complicated views --\u003e\n\n\u003c/com.skydoves.transformationlayout.TransformationLayout\u003e\n```\n\n### Transform into a view\nFor instance, you can transform a floating button into a CardView as you've seen in the example below:\n\n\u003cimg src=\"https://user-images.githubusercontent.com/24237865/75549488-25321700-5a73-11ea-8908-609592907e84.gif\" align=\"right\" width=\"280\"/\u003e\n\n```gradle\n\u003ccom.skydoves.transformationlayout.TransformationLayout\n    android:id=\"@+id/transformationLayout\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    app:transformation_duration=\"550\"\n    app:transformation_targetView=\"@+id/myCardView\"\u003e\n\n  \u003ccom.google.android.material.floatingactionbutton.FloatingActionButton\n      android:id=\"@+id/fab\"\n      android:layout_width=\"wrap_content\"\n      android:layout_height=\"wrap_content\"\n      android:backgroundTint=\"@color/colorPrimary\"\n      android:src=\"@drawable/ic_write\"/\u003e\n\u003c/com.skydoves.transformationlayout.TransformationLayout\u003e\n\n\u003ccom.google.android.material.card.MaterialCardView\n    android:id=\"@+id/myCardView\"\n    android:layout_width=\"240dp\"\n    android:layout_height=\"312dp\"\n    android:layout_marginLeft=\"30dp\"\n    android:layout_marginTop=\"30dp\"\n    app:cardBackgroundColor=\"@color/colorPrimary\" /\u003e\n```\n\n#### Bind a TargetView\nWith the attribute below in your XML file, you can bind a `targetView` that should be transformed from the `TransformationLayout`. If you bind a targetView with a `TransformationLayout`, the targetView's visibility will be `GONE` by default.\n\n```gradle\napp:transformation_targetView=\"@+id/myCardView\"\n```\n\nYou can also bind a targetView with a `TransformationLayout` using `bindTargetView` method like the code below:\n\n```kotlin\ntransformationLayout.bindTargetView(myCardView)\n```\n\n#### Starting and finishing the transformation\nAfter binding a targetView, we can start or finish transformation using the below methods.\u003cbr\u003e\n```kotlin\n// start transformation when touching the fab.\nfab.setOnClickListener {\n  transformationLayout.startTransform()\n}\n\n// finish transformation when touching the myCardView.\nmyCardView.setOnClickListener {\n  transformationLayout.finishTransform()\n}\n```\nHere are other functionalities to starting and finishing transformation.\n\n```kotlin\n// starts and finishes transformation 1000 milliseconds later.\n// If we use this method on onCreate() method, it will starts transformation automatically 200ms later.\ntransformationLayout.startTransformWithDelay(200)\ntransformationLayout.finishTransformWithDelay(200)\n\n// starts and finishes transformation with stopping a parent layout.\ntransformationLayout.startTransform(parent)\ntransformationLayout.finishTransform(parent)\n```\n\n### OnTransformFinishListener\nWe can listen a `TransformationLayout` is transformed or not using `OnTransformFinishListener`. \u003cbr\u003e\n```kotlin\ntransformationLayout.setOnTransformFinishListener {\n  Toast.makeText(context, \"is transformed: $it\", Toast.LENGTH_SHORT).show()\n}\n```\nHere is the __Java__ way.\n```java\ntransformationLayout.onTransformFinishListener = new OnTransformFinishListener() {\n  @Override public void onFinish(boolean isTransformed) {\n    Toast.makeText(context, \"is transformed:\" + isTransformed, Toast.LENGTH_SHORT).show();\n  }\n};\n```\n\n### Transform into an Activity\nWe can implement transformation between activities easily using `TransformationActivity` and `TransformationCompat`.\n\n\u003cimg src=\"/preview/preview2.gif\" align=\"right\" width=\"270\"/\u003e\n\nHere is an example of transforming a floating action button to Activity. \u003cbr\u003e\nWe don't need to bind a targetView.\n\n```gradle\n\u003ccom.skydoves.transformationlayout.TransformationLayout\n    android:id=\"@+id/transformationLayout\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    app:transformation_duration=\"550\"\u003e\n\n  \u003ccom.google.android.material.floatingactionbutton.FloatingActionButton\n      android:id=\"@+id/fab\"\n      android:layout_width=\"wrap_content\"\n      android:layout_height=\"wrap_content\"\n      android:backgroundTint=\"@color/colorPrimary\"\n      android:src=\"@drawable/ic_write\"/\u003e\n\u003c/com.skydoves.transformationlayout.TransformationLayout\u003e\n```\n#### onTransformationStartContainer\nWe should add `onTransformationStartContainer()` to the Activity that has the floating action button. If your view is in the fragment, the code should be added to the fragment's Activity. It must be called before `super.onCreate`.\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n    onTransformationStartContainer() // should be called before super.onCreate().\n    super.onCreate(savedInstanceState)\n    setContentView(R.layout.activity_main)\n}\n```\nHere is the Java way.\n```java\nTransformationCompat.onTransformationStartContainer(this);\n```\n\n#### TransformationAppCompatActivity\nExtends `TransformationAppCompatActivity` or `TransformationActivity` to your activity that will be transformed.\n```kotlin\nclass DetailActivity : TransformationAppCompatActivity()\n```\nHere is the Java way.\n```java\npublic class DetailActivity extends TransformationAppCompatActivity \n```\n\n#### TransformationCompat\nAnd start the `DetailActivity` using the `TransformationCompat.startActivity` method.\n```kotlin\nval intent = Intent(context, DetailActivity::class.java)\nTransformationCompat.startActivity(transformationLayout, intent)\n```\nHere is the Java way.\n```java\nIntent intent = new Intent(context, DetailActivity.class);\nTransformationCompat.startActivity(transformationLayout, intent);\n```\n\n### Manually Transform into an Activity\n\n\u003cimg src=\"/preview/preview2.gif\" align=\"right\" width=\"270\"/\u003e\n\nHere is an example of transforming a floating action button to Activity. \u003cbr\u003e\nWe don't need to bind a targetView.\n\n```gradle\n\u003ccom.skydoves.transformationlayout.TransformationLayout\n    android:id=\"@+id/transformationLayout\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    app:transformation_duration=\"550\"\u003e\n\n  \u003ccom.google.android.material.floatingactionbutton.FloatingActionButton\n      android:id=\"@+id/fab\"\n      android:layout_width=\"wrap_content\"\n      android:layout_height=\"wrap_content\"\n      android:backgroundTint=\"@color/colorPrimary\"\n      android:src=\"@drawable/ic_write\"/\u003e\n\u003c/com.skydoves.transformationlayout.TransformationLayout\u003e\n```\n#### onTransformationStartContainer\nWe should add `onTransformationStartContainer()` to the Activity that has the floating action button. If your view is in the fragment, the code should be added to the fragment's Activity. It must be called before `super.onCreate`.\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n    onTransformationStartContainer() // should be called before super.onCreate().\n    super.onCreate(savedInstanceState)\n    setContentView(R.layout.activity_main)\n}\n```\nHere is the Java way.\n```java\nTransformationCompat.onTransformationStartContainer(this);\n```\n\n#### startActivity\nAnd we should call `startActivity` with bundle and intent data.\u003cbr\u003e\nWe should get a `bundle` using `withActivity` method. It needs a context and any name of transition. \u003cbr\u003e\nThe `bundle` must be used as `startActivity`'s parameter.\u003cbr\u003e\nWe should put parcelable data to the intent using `getParcelableParams()` method.\u003cbr\u003e\nThe extra name of the parcelable data can be anything, and it will be reused later.\n```kotlin\nfab.setOnClickListener {\n    val bundle = transformationLayout.withActivity(this, \"myTransitionName\")\n    val intent = Intent(this, DetailActivity::class.java)\n    intent.putExtra(\"TransformationParams\", transformationLayout.getParcelableParams())\n    startActivity(intent, bundle)\n}\n```\nIf we want to get bundle data in RecyclerView or other classes, \u003cbr\u003e\nwe can use `withView` and `withContext` instead of `withActivty`.\n```kotlin\n// usage in the RecyclerView.Adapter\noverride fun onBindViewHolder(holder: PosterViewHolder, position: Int) {\n   val bundle = transformationLayout.withView(holder.itemView, \"myTransitionName\")\n}\n```\n\nHere is the __Java__ way.\n```java\nBundle bundle = transformationLayout.withActivity(this, \"myTransitionName\");\nIntent intent = new Intent(this, DetailActivity.class);\nintent.putExtra(\"TransformationParams\", transformationLayout.getParcelableParams());\nstartActivity(intent, bundle);\n```\n\n#### onTransformationEndContainer\nAnd finally, we should add `onTransformationEndContainer()` to the Activity that will be started. \u003cbr\u003e\nIt must be added before `super.onCreate`.\n\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n    onTransformationEndContainer(intent.getParcelableExtra(\"TransformationParams\"))\n    super.onCreate(savedInstanceState)\n    setContentView(R.layout.activity_detail)\n}\n```\n\nHere is the __Java__ way.\n```java\nTransformationLayout.Params params = getIntent().getParcelableExtra(\"TransformationParams\");\nTransformationCompat.onTransformationEndContainer(this, params);\n```\n\n### Transform into a Fragment\nWe can implement transformation between fragments for a single Activity application.\u003cbr\u003e\nHere is an example of transforming a floating action button in Fragment A to Fragment B.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/24237865/80108763-a1e6fa80-85b7-11ea-9350-f9d8ebc46310.gif\" align=\"right\" width=\"270\"/\u003e\n\n```gradle\n\u003ccom.skydoves.transformationlayout.TransformationLayout\n    android:id=\"@+id/transformationLayout\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    app:transformation_duration=\"550\"\u003e\n\n  \u003ccom.google.android.material.floatingactionbutton.FloatingActionButton\n      android:id=\"@+id/fab\"\n      android:layout_width=\"wrap_content\"\n      android:layout_height=\"wrap_content\"\n      android:backgroundTint=\"@color/colorPrimary\"\n      android:src=\"@drawable/ic_write\"/\u003e\n\u003c/com.skydoves.transformationlayout.TransformationLayout\u003e\n```\n\n#### onTransformationStartContainer\nWe should call `onTransformationStartContainer()` in the Fragment A that has the floating action button.\n\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n  super.onCreate(savedInstanceState)\n  onTransformationStartContainer()\n}\n```\n\nHere is the Java way.\n```java\nTransformationCompat.onTransformationStartContainer(this);\n```\n\n#### getBundle and addTransformation\nWe should get a bundle from the `TransformationLayout` and put it into the argument.\u003cbr\u003e\nAnd in the fragment manager's transaction, we should add the `TransformationLayout` using `addTransformation` method.\n\n```kotlin\nval fragment = MainSingleDetailFragment()\nval bundle = transformationLayout.getBundle(\"TransformationParams\")\nbundle.putParcelable(MainSingleDetailFragment.posterKey, poster)\nfragment.arguments = bundle\n\nrequireFragmentManager()\n  .beginTransaction()\n  .addTransformation(transformationLayout)\n  .replace(R.id.main_container, fragment, MainSingleDetailFragment.TAG)\n  .addToBackStack(MainSingleDetailFragment.TAG)\n  .commit()\n}\n```\nHere is the Java way\n```java\nMainSingleDetailFragment fragment = new MainSingleDetailFragment();\nBundle bundle = transformationLayout.getBundle(\"TransformationParams\", \"transitionName\");\nfragment.setArguments(bundle);\n\nFragmentTransaction fragmentTransaction = requireFragmentManager().beginTransaction();\nTransformationCompat.addTransformation(\n    fragmentTransaction, transformationLayout, \"transitionName\");\nfragmentTransaction.replace(R.id.main_container, fragment, MainSingleDetailFragment.TAG)\n    .addToBackStack(MainSingleDetailFragment.TAG)\n    .commit();\n```\n#### Transition name in Fragment A\nWe must set a specific transition name to the `TransformationLayout`.\u003cbr\u003e\nIf you want to transform a recyclerView's item, set transiton name in `onBindViewHolder`.\n```kotlin\ntransformationLayout.transitionName = \"myTransitionName\"\n```\nHere is the Java way.\n```java\ntransformationLayout.setTransitionName(\"myTransitionName\");\n```\n#### onTransformationEndContainer in Fragment B\nWe should get a `TransformationLayout.Params` from the arguments, and call `onTransformationEndContainer` method.\u003cbr\u003e\nIt must be called in `onCreate` method.\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n  super.onCreate(savedInstanceState)\n\n  val params = arguments?.getParcelable\u003cTransformationLayout.Params\u003e(\"TransformationParams\")\n  onTransformationEndContainer(params)\n}\n```\nHere is the Java way.\n```java\nTransformationLayout.Params params = getArguments().getParcelable(\"TransformationParams\");\nTransformationCompat.onTransformationEndContainer(this, params);\n```\n#### Transition name in Fragment B\nAnd finally set the specific transition name (same as the transformationLayot in Fragment A) \u003cbr\u003e\nto the target view in Fragment B in `onViewCreated`.\n```kotlin\noverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n  super.onViewCreated(view, savedInstanceState)\n   \n  detail_container.transitionName = \"myTransitionName\"\n}\n```\n\n\n## TransformationLayout Attributes\nAttributes | Type | Default | Description\n--- | --- | --- | ---\ntargetView | resource id | none | Bind a targetView that will be transformed. \nduration | Long | 350L | Duration of the transformation.\npathMotion | Motion.ARC, Motion.LINEAR | default layout | Indicates that this transition should be drawn as the which path.\ncontainerColor | Color | Color.TRANSPARENT | Set the container color to be used as the background of the morphing container.\nallContainerColor | Color | Color.TRANSPARENT | The all container colors (start and end) to be used as the background of the morphing container.\nscrimColor | Color | Color.TRANSPARENT | Set the color to be drawn under the morphing container.\ndirection | Direction.AUTO, Direction.ENTER, Direction.RETURN | Direction.AUTO | Set the direction to be used by this transform.\nfadeMode | FadeMode.IN, FadeMode.OUT, FadeMode.CROSS, FadeMode.THROUGH | FadeMode.IN | Set the FadeMode to be used to swap the content of the start View with that of the end View.\nfitMode | FitMode.AUTO, FitMode.WIDTH, FitMode.HEIGHT | FitMode.AUTO | Set the fitMode to be used when scaling the incoming content of the end View.\nstartElevation | Float | ELEVATION_NOT_SET | The elevation that will be used to render a shadow around the container at the start of the transition.\nendElevation | Float | ELEVATION_NOT_SET | The elevation that will be used to render a shadow around the container at the end of the transition.\nelevationShadowEnabled | Boolean | true if (version \u003e Pie) | Whether shadows should be drawn around the container to approximate native elevation shadows on the start and end views.\nholdAtEndEnabled | Boolean | false | Whether to hold the last frame at the end of the animation.\n\n## Additional 🎈\nYou can reference the usage of the TransformationLayout in another repository [MarvelHeroes](https://github.com/skydoves/MarvelHeroes). \u003cbr\u003e\nA demo application based on modern Android application tech-stacks and MVVM architecture.\n\n![screenshot](https://user-images.githubusercontent.com/24237865/80602029-9426ee80-8a69-11ea-866d-4e31b6526ab2.png)\n\n## Find this library useful? :heart:\nSupport it by joining __[stargazers](https://github.com/skydoves/transformationlayout/stargazers)__ for this repository. :star: \u003cbr\u003e\nAnd __[follow](https://github.com/skydoves)__ me for my next creations! 🤩\n\n# License\n```xml\nCopyright 2020 skydoves (Jaewoong Eum)\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","funding_links":["https://github.com/sponsors/skydoves","https://www.paypal.me/skydoves","https://www.buymeacoffee.com/skydoves"],"categories":["Index","Libraries","Kotlin"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskydoves%2FTransformationLayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskydoves%2FTransformationLayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskydoves%2FTransformationLayout/lists"}