以编程方式设置MotionLayout中的边距

8

我有一些需要在程序中设置边距的视图(从applyWindowInsets侦听器),但是视图似乎忽略了我用代码设置的任何边距,即使我没有对边距进行动画处理。

我可以很好地设置填充,但我无法仅使用填充来完成我需要的工作。

问题似乎与MotionLayout有关,因为如果它是ConstraintLayout,则运行良好。

我一直在使用这个util方法。

public static void addTopMargin(View v, int margin) {
    ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin += margin;
}

我一直在使用一种解决方法,虽然并非所有情况下都有效,但足以让我完成所需的工作。如果您将要控制的视图放置在LinearLayout中,则可以控制子对象上需要的任何属性,而MotionLayout将控制LinearLayout上的所有属性。 - lbenedetto
2个回答

8
您遇到的问题是,MotionLayout从指定的ConstraintSets中继承其边距,因此更改基础边距实际上并没有起作用。为使其生效,您需要针对定义MotionScene的一个或两个ConstraintSets进行操作。
val motionLayout = findViewById(R.id.motionLayoutId)
motionLayout.getConstraintSet(R.id.startingConstraintSet)?
    .setMargin(targetView.id, anchorId, value)

您也可以使用 let 对多个视图进行此操作:
val motionLayout = findViewById(R.id.motionLayoutId)
motionLayout.getConstraintSet(R.id.startingConstraintSet)?.let {
    setMargin(firstView.id, anchorId, value)
    setMargin(secondView.id, anchorId, value)
}

对于顶部边距,请使用ConstraintSet.TOP等。请记住,如果您不想对该边距进行动画处理,您需要为起始和结束的ConstraintSet都进行赋值。

1

我想在UnOrthodox的解决方案中添加一个简单的注释,以防万一您不需要动画那个margin,您需要保持基本的margin并添加ConstraintSets margin:

public static void addTopMargin(View v, int margin) {
    ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin += margin;
    MotionLayout root = findViewById(R.id.motion_layout);
    root.getConstraintSet(R.id.start).setMargin(firstView.id, anchorId, margin);
    root.getConstraintSet(R.id.end).setMargin(firstView.id, anchorId, margin);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接