MotionLayout动画场景下TextInputLayout预览崩溃、点击无焦点问题求助
问题根因
XML预览渲染崩溃
- 属于Android Studio布局渲染器的兼容性问题:你在MotionScene的start状态将包含TextInputLayout的
second_layout设置为constraintEnd_toStartOf="parent",即初始时完全位于父容器可视区域外。TextInputEditText的测量逻辑依赖父容器可视状态,渲染器测量屏幕外带hint动画的输入组件时触发空指针。移除TextInputEditText后异常消失也验证了该逻辑。
真机输入框无焦点
- 属于MotionLayout嵌套ConstraintLayout的已知触控映射bug:你给子ConstraintLayout设置了0dp+百分比宽高,位移动画结束后MotionLayout没有正确同步子布局的触控区域映射,导致输入框视觉位置和实际响应区域不匹配,点击时仅触发键盘弹出但输入框未拿到焦点。输入内容后TextInputLayout会触发重测量更新触控区域,因此再次点击可正常获取焦点,清空内容后回到初始测量状态,问题复现。
可行解决方案
预览渲染问题修复
除了你已经验证的修改过渡方向方案外,还可以选择以下两种兼容方案:
- 给TextInputEditText添加
tools:visibility="visible"属性,强制预览时输入框保持可视状态,规避测量异常 - 调试阶段临时给start状态的
second_layout添加tools:layout_constraintStart_toStartOf="parent",仅作用于预览不影响实际运行逻辑
输入框无焦点问题修复
按优先级从高到低尝试:
- 修改子ConstraintLayout的宽高声明
移除MotionScene里子ConstraintLayout的百分比宽高相关属性,直接用match_parent声明宽高,修改后约束规则如下:
<Constraint android:id="@+id/second_layout" android:layout_width="match_parent" android:layout_height="match_parent" motion:layout_constraintStart_toEndOf="parent" />
删除原有的layout_constraintWidth_default、layout_constraintHeight_default、宽高百分比相关属性,避免触发多层约束布局的测量冲突。
- 动画结束后主动触发重布局
在调用transitionToEnd()后监听动画结束事件,强制子布局重测量更新触控区域,代码如下:
bind.motionLayout.transitionToEnd(); bind.motionLayout.addTransitionListener(new MotionLayout.TransitionListener() { @Override public void onTransitionCompleted(MotionLayout motionLayout, int currentId) { if (currentId == R.id.b_end) { bind.secondLayout.requestLayout(); // 可额外添加主动请求焦点逻辑,符合用户操作预期 bind.textLayoutInput.getEditText().requestFocus(); } } @Override public void onTransitionStarted(MotionLayout motionLayout, int startId, int endId) {} @Override public void onTransitionChange(MotionLayout motionLayout, int startId, int endId, float progress) {} @Override public void onTransitionTrigger(MotionLayout motionLayout, int triggerId, boolean positive, float progress) {} });
- 兜底方案:移除嵌套ConstraintLayout
如果上述方案均无效,直接将三个子ConstraintLayout替换为FrameLayout,所有约束逻辑都写在MotionScene中,彻底规避多层约束布局的兼容性问题。
内容的提问来源于stack exchange,提问作者Monsef Khalfaoui
相关产品推荐
相关产品推荐

