【问题标题】:android:visibility changes to children of MotionLayoutandroid:对 MotionLayout 子项的可见性更改
【发布时间】:2019-07-23 15:58:10
【问题描述】:

我一定遗漏了 android:visibility 在动作布局中的变化。这是我的布局的简化版本。

<MotionLayout>
 <ImageView android:id="@+id/HeaderBackground" />
Bunch of image views, Text views that are constrainted to the HeaderBackground. 
<RecyclerView android:visibility="visible">
<EditText android:visibility="visible">
<CustomViewGroup1 android:visibility="gone">
</MotionLayout>

我有一个motionScreen,它基于回收器视图设置一个Transition onswipe,以降低HeaderBackground 的高度并隐藏一些图像/文本视图(即折叠工具栏)。 但是,如果有一些致命错误,我想在 RecyclerView 的顶部/前面显示 CustomViewGroup1,但是将 RecyclerView 的可见性切换为消失并且将 CustomViewGroup1 切换为可见不会使 CustomViewGroup1 显示。

我可以将 CustomViewGroup 组移出 MotionLayout 并添加一个框架布局作为 Activity 的根并隐藏整个 MotionLayout。但这不太理想,因为我必须复制工具栏和图标。所以我想问题是关于可见性变化和潜在的 z 排序?

我正在使用androidx.constraintlayout:constraintlayout:2.0.0-beta2

【问题讨论】:

  • 遇到了同样的问题,使用 alpha 解决了
  • @RameesThattarath 澄清您切换回 alpha 并解决了问题?如果是哪个版本。
  • androidx.constraintlayout:constraintlayout:2.0.0-beta1
  • 嗯...谢谢您的回复。但是,2.0.0-beta12.0.0-beta2 之间的行为相同。

标签: android android-motionlayout


【解决方案1】:

原来这是我对 MotionLayout 工作原理的缺乏经验。默认情况下,MotionLayout 控制其中所有视图的可见性。但是您可以通过使用app:visibilityMode="ignore" 属性&lt;ConstraintSet&gt; 中定义视图来选择退出子视图

在我的情况下,&lt;CustomViewGroup1&gt; 看起来像这样......

<Constraint
      android:id="@id/CustomViewGroup1"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/HeaderBackground"
      app:layout_constraintVertical_weight="1"
      app:visibilityMode="ignore" />

这在 both 折叠和展开的 ConstraintSets 中定义相同,因为我不希望它在滚动回收器视图时移动/动画。

感谢 John Hoford 在另一个频道提供的建议。

【讨论】:

  • 谢谢。经过几天的修复,这一直是我的救星。
  • motion:visibilityMode="ignore" 为我工作
【解决方案2】:

我的方法是从运动布局中排除视图,忽略场景中的可见性,以便它可以编程并继承最终约束集中的约束。

documentation 提到了app:applyMotionScene="boolean",但它没有告诉你在哪里。它必须在PropertySet

另外visibilityMode 也只在PropertySet 内为我工作

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition
        ...
    </Transition>

    <ConstraintSet android:id="@+id/start">

        <Constraint android:id="@id/viewId">
            <PropertySet
                app:applyMotionScene="false"
                app:visibilityMode="ignore" />
        </Constraint>

    </ConstraintSet>

    <ConstraintSet
        android:id="@+id/end"
        motion:deriveConstraintsFrom="@id/start">
        ...
    </ConstraintSet>

</MotionScene>

小心从运动场景自动导入的应用命名空间,这是错误的,您必须使用与布局上相同的名称。

这样做的好处是:

  • 场景中没有宽度、高度或约束
  • 不需要重复属性,因为是从开始约束集派生的

【讨论】:

  • 马恩!!!你救了我... applyMotionScene 是真正的交易。我在文档上看到了它,但对我来说没有任何意义......哦,谢谢
  • @PaulOkeke 检查这个系列 youtu.be/o8c1RO3WgBA 并欢迎乐于提供帮助
【解决方案3】:

编程方式

View clickableArea = motionLayout.findViewById(R.id.video_overlay_thumbnail);    
motionLayout.getConstraintSet(R.id.start).getConstraint(clickableArea.getId()).propertySet.mVisibilityMode = 1; // 1 - ignore or 0 - normal
clickableArea.setVisibility(GONE);

【讨论】:

  • 非常好..完美运行!!谢谢:)
【解决方案4】:

visibilityMode 属性设置为 normal,使用 2.0.0-beta3 对我来说效果很好 em>。

 app:visibilityMode="normal"
 android:visibility="visible"

【讨论】:

  • 默认正常
【解决方案5】:

您可以通过这种方式以程序方式更改 Motion 布局的可见性子项:

fun View.changeVisibility(visibility: Int) {
        val motionLayout = parent as MotionLayout
        motionLayout.constraintSetIds.forEach {
            val constraintSet = motionLayout.getConstraintSet(it) ?: return@forEach
            constraintSet.setVisibility(this.id, visibility)
            constraintSet.applyTo(motionLayout)
        }
    }

【讨论】:

    【解决方案6】:

    根据您的用例,另一个选项是确保您要控制其可见性的视图不是 MotionLayout 的直接后代。将它放在容器视图中,您就可以将可见性设置为正常

    【讨论】:

      猜你喜欢
      • 2019-08-28
      • 2022-09-27
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 2017-08-04
      • 2017-07-25
      • 2013-01-02
      • 1970-01-01
      相关资源
      最近更新 更多