Je joue avec MotionLayout et j'ai un problème étrange
Quand j'ai changé la version de la bibliothèque utilisée de com.android.support.constraint:constraint-layout:2.0.0-alpha2
en com.android.support.constraint:constraint-layout:2.0.0-alpha3
mon application a planté:
E/AndroidRuntime: FATAL EXCEPTION: main Process: ru.sergik.collapsibleexoplayer, PID: 1376 java.lang.NullPointerException: Attempt to invoke virtual method 'int androidx.constraintlayout.motion.widget.MotionScene.getDuration()' on a null object reference at androidx.constraintlayout.motion.widget.MotionLayout.dispatchDraw(MotionLayout.java:1634) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:2072) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19306) at android.view.View.draw(View.java:20093) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.draw(View.java:20373) at com.android.internal.policy.DecorView.draw(DecorView.java:980) at android.view.View.updateDisplayListIfDirty(View.java:19315) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3496) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3283) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2818) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1780) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7827) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911) at android.view.Choreographer.doCallbacks(Choreographer.java:723) at android.view.Choreographer.doFrame(Choreographer.java:658) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
En effectuant un débogage, j'ai trouvé des différences dans les versions de MotionLayout à l'origine de ce crash:
Comme vous pouvez le voir dans alpha-3 this.mDevModeDraw.draw(canvas, this.mFrameArrayList, this.mScene.getDuration(), this.mDebugPath);
sera appelé et provoquera un crash lors de la tentative d'obtention de la durée de la scène de mouvement this.mScene.getDuration()
, mais dans alpha-2, il ne sera pas appelé en raison de conditions if différentes.
Comment dois-je résoudre ce problème?
3 Réponses :
Pour moi, cela s'est produit lorsque j'ai sous- MotionLayout
et gonflé son contenu avec la <merge...
J'ai oublié que les paramètres de la balise de fusion sont ignorés et que vous devez les réappliquer manuellement dans le code.
Alors ça ressemble à ça maintenant:
class SomeLayout : MotionLayout { constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { inflate(context, R.layout.some_layout, this) loadLayoutDescription(R.xml.some_motion_scene) setTransition(R.id.start, R.id.end) } ...
Vous n'avez pas publié votre XML mais vous pouvez vérifier si vous disposez de l'attribut app:layoutDescription
sur l'ensemble de mise en page.
Correction du même problème en mettant à jour la bibliothèque à partir de
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
à
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
Pour vous aider, nous aurions besoin de voir comment vous utilisez MotionLayout, en particulier votre MotionScene.
Pour moi, cela s'est probablement produit lorsque j'ai utilisé une balise de fusion et que j'ai gonflé ma propre sous-classe MotionLayout avec. Cependant, sur alpha2, cela ne plante pas mais ne fonctionne pas non plus.