0

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.

GV_FiQst
  • 1,487
  • 14
  • 30

2 Answers2

1

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.

esentsov
  • 6,372
  • 21
  • 28
  • I'm new to the jetifier tool (never used it) so I might ask silly questions. First of all is where to put this config file? Is it used only for command sake or also gradle should use it somehow? And the `config.json` you posted is just an example or I can use it `as is` with specified commands? – GV_FiQst Sep 28 '19 at 22:54
  • The config is for the jetifier command only. The posted `config.json` should work as is. – esentsov Sep 29 '19 at 09:40
  • I've created a sample and put a link into the post, please check it out. – esentsov Sep 29 '19 at 09:40
  • I checked out your sample project but it didn't work. It said `Unresolved reference: JetifierPlugin`. So I gave a try to your previous answer to use jetifier tool and just to generate new lib with different package. I've put it to 'libs' folder and it worked. Thank you very much! – GV_FiQst Sep 30 '19 at 10:30
0

I faced similar issues - the only possible way to avoid the class collision is to rebuild one of the dependencies with the different package name. It could be done by downloading the code of one of the libraries and recompile it manually on your PC. For example from here.

But I would recommend you to use ConstraintLayout library version 2.0

implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta2'

or

implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'

if you are using AndroidX.

Is contains both ConstraintLayout and MotionLayout so they would not create a conflict in your code. Some small adjustments may be needed in your current code though.

Hope it helps.

Pavlo Ostasha
  • 14,527
  • 11
  • 35