Программно установить поля в MotionLayout

У меня есть некоторые представления, которым нужны некоторые поля, установленные программно (из прослушивателя applyWindowInsets), но представления, кажется, игнорируют любые поля, которые я установил с помощью своего кода, даже если я не анимирую поля.

Я могу установить отступы просто отлично, но я не могу выполнить то, что мне нужно, используя только отступы.

Проблема, похоже, связана с MotionLayout, поскольку он отлично работает, если это ConstraintLayout.

Я использовал этот метод util.

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

person lbenedetto    schedule 03.06.2019    source источник
comment
Я использовал обходной путь, который работает не во всех случаях, но достаточно, чтобы я смог выполнить то, что мне было нужно. Если вы помещаете представление, которым хотите управлять, в LinearLayout, вы можете управлять любыми свойствами, которые вам нужны для дочернего объекта, а макет движения будет управлять всеми свойствами LinearLayout.   -  person lbenedetto    schedule 04.09.2019


Ответы (2)


Проблема, с которой вы столкнулись, заключается в том, что MotionLayout получает свои поля из назначенного ConstraintSets, поэтому изменение базового поля на самом деле ничего не делает. Чтобы заставить это работать, вам нужно настроить таргетинг на один или оба ConstraintSets, которые определяют MotionScene:

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.

person UnOrthodox    schedule 26.05.2020

Просто добавьте простое примечание к решению UnOrthodox, что в случае, если вам не нужно анимировать это поле, вам нужно будет сохранить базовое поле с добавлением поля ConstraintSets:

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);
}
person Ahmed Abdel-Mohsen    schedule 28.02.2021