Search code examples
androidandroid-layoutkotlinandroid-gradle-pluginandroid-motionlayout

Use MotionLayout and ConstraintLayout dependencies with different versions


I've been using ConstraintLayout of version 1.1.2 for a while now. It was working perfectly. Then new MotionLayout came up and I thought why not to try it out. And everything seemed fine.

However I made a mistake of using it in production. Only after some time I noticed some bug reports on ConstraintLayout working not properly. But there are some screens already that depend on MotionLayout, removing which will cause a lot of refactoring.

Is it possible to use MotionLayout(v2.0.0-alpha-05/beta-02) and ConstraintLayout(v1.1.3) for the same project, so that screens that work with MotionLayout would have v2.0.0 and screens that work with ConstraintLayout only would have v1.1.3? Is there some packaging tool to move MotionLayout to a different package? I tried to use shadowJar gradle plugin but failed because MotionLayout is an *.aar dependency not *.jar.


Solution

  • Edit: I've created a sample where I use jetifier gradle plugin from aosp to rewrite the package names and demonstrate how to use both 1.1.3 and 2.0.0-beta versions in the same project.

    You can use jetifier with custom config file to rewrite package name. Just run it on both constraintlayout-2.0.0-beta2.aar and constraintlayout-solver-2.0.0-beta2.jar like this:

    ./jetifier-standalone  -i constraintlayout-2.0.0-beta2.aar -o myconstraintlayout-2.0.0-beta2.aar -c config.json
    ./jetifier-standalone  -i constraintlayout-solver-2.0.0-beta2.jar -o myconstraintlayout-solver-2.0.0-beta2.jar -c config.json
    

    where config.json is the custom config like this:

    {
      "restrictToPackagePrefixes": [
        "androidx/"
      ],
      "reversedRestrictToPackagePrefixes": [],
      "rules": [
        {
          "from": "androidx/(.*)",
          "to": "myandroidx/{0}"
        },
      ],
      "packageMap": [
        {
          "from": "androidx/constraintlayout/widget",
          "to": "myandroidx/constraintlayout/widget"
        }
      ],
      "pomRules": [],
      "versions": {
        "latestReleased": {}
      },
      "map": {
        "types": {}
      },
      "proGuardMap": {
        "rules": {
          "androidx/{any}": [
            "myandroidx/{any}"
          ]
        }
      },
      "stringsMap": {
        "types": {}
      }
    }
    

    You can check the original config file to find out file format.

    After that you can use myconstraintlayout-2.0.0-beta2.aar and myconstraintlayout-solver-2.0.0-beta2.jar in your project. Obviously you'll have to change package name for MotionLayout in your project.

    It should be possible to automate the process by writing a gradle plugin also.

    Edit: it's probably better to repackage constraintlayout-1.1.3, so you can easily update MotionLayout with new versions when they are released.