Android-анимация макетов ограничений - PullRequest
0 голосов
/ 22 мая 2018

Я хочу анимировать два ConstraintLayouts - один является потомком другого.

Я знаю, что анимация работает только на прямых потомках ConstraintLayout, так что это мой макет:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/cl"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#393939"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:visibility="visible">

        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Move me!"
            android:textColor="#fff"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.8" />
    </android.support.constraint.ConstraintLayout>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Animate" />
</android.support.constraint.ConstraintLayout>

с корневым макетом ConstraintLayout и внутренним ConstraintLayout с фоновым цветом и TextView.Внутренняя компоновка вначале установлена ​​на gone.

Я хочу постепенно затухать во внутренней ConstraintLayout (установите ее видимость на View.VISIBLE), а также переместите TextView вверх (установите ее vertical Bias на меньшее число).Поскольку я не могу анимировать внутренние дочерние представления, я создаю 4 набора ограничений - csA для анимации видимости внутренних ConstraintLayout и csB для анимации, чтобы переместить TextView вверх.

class MainActivity : AppCompatActivity() {
    val csA1 = ConstraintSet()
    val csA2 = ConstraintSet()

    val csB1 = ConstraintSet()
    val csB2 = ConstraintSet()

    lateinit var btn: Button
    lateinit var cl: ConstraintLayout
    lateinit var root: ConstraintLayout

    var switch = false


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        root = findViewById(R.id.root_layout)
        val tv: TextView = findViewById(R.id.textview)
        cl = findViewById(R.id.cl)
        btn = findViewById(R.id.button)

        btn.setOnClickListener { toggle() }

        csA1.clone(root)
        csA2.clone(csA1)
        csA2.setVisibility(R.id.cl, View.VISIBLE)

        csB1.clone(cl)
        csB2.clone(csB1)
        csB2.setVerticalBias(R.id.textview, 0.3f)

    }

    fun toggle() {
        TransitionManager.beginDelayedTransition(root)
        val cs = if (!switch) csA2 else csA1
        cs.applyTo(root)
        val vsB = if (!switch) csB2 else csB1

        TransitionManager.beginDelayedTransition(cl)
        vsB.applyTo(cl)

        switch = !switch
        btn.text = "switch: $switch"
    }
}

Первое нажатие кнопки может работать, но при втором нажатии раскладка не скрывается, и вид остается на своем месте.Текст обрезается до первой буквы, полный текст отображается при следующем нажатии.Когда для триггера задано значение от true до false, фон в течение очень короткого времени мигает белым, а затем снова становится серым.

В этом проекте больше ничего нет.Если я отключаю одну из анимаций, другая работает без проблем.

Что я пробовал:

  • Задержка vsB через обработчик и postDelayed, а также настройкапользовательский переход с startDelay с duration анимации видимости.
   
    Handler().postDelayed({
        TransitionManager.beginDelayedTransition(cl)
        vsB.applyTo(cl)
    }, 450)
  • С обработчиком и задержкой 450 ms (я не проверял минимальный предел этого) - анимация работает.Он не запаздывает, раскладка отображается и скрывается должным образом при каждом нажатии кнопки, а текстовое представление перемещается вверх.Но это не совсем мое требование.Мне нужно анимировать их одновременно или даже лучше: с задержкой 50 мс при движении вверх.

  • С обработчиком и задержкой 1 ms раскладка показана на первомнажмите, TextView уже находится в своем окончательном положении (без движения).

  • Пользовательский переход с startDelay, который реагирует как версия без чего-либо: TextView.text обрезаетсядо первой буквы фон мигает белым и снова становится серым.Кажется, что переходы не имеют никакого эффекта, даже с большим startDelay (duration + 200, например).

   
    fun toggle() {
        val duration = 200L
        val transitionA = AutoTransition()
        transitionA.duration = duration

        val transitionB = AutoTransition()
        transitionB.startDelay = duration

        TransitionManager.beginDelayedTransition(root, transitionA)
        val cs = if (!switch) csA2 else csA1
        cs.applyTo(root)

        val vsB = if (!switch) csB2 else csB1

        TransitionManager.beginDelayedTransition(cl,transitionB)
        vsB.applyTo(cl)

        switch = !switch
        btn.text = "switch: $switch"
    }

Я тестировал это на эмуляторе на API27 и Samsung S6 с API 24. Другая техническая информация:

   
    compileSdkVersion 27

    minSdkVersion 21
    targetSdkVersion 27

    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'


    Android Studio Version 3.1.2
    Android SDK Tools 26.1.1 

Возможна ли одновременная анимация двух ConstraintLayouts?

1 Ответ

0 голосов
/ 23 мая 2018

Поскольку я до сих пор не могу комментировать (недостаточно повторений), я напишу это здесь, но прочитаю как комментарий.
Вы думаете о ConstraintSets неправильно.
Если вы просто хотите установить некоторыевещи видны и анимировать их в другом месте, вам нужно сделать два XML.Они должны иметь одинаковые представления внутри (независимо от того, видимы они или нет), а затем применять их через TransitionManager и ConstraintSets.
Простой пример без кода:

У вас есть файл ConstraintLayout xml с одним ImageView в нем.В первом XML-файле он находится в верхней части макета, а во втором - в нижней части.Теперь, когда вы клонируете эти макеты и применяете их друг к другу (вероятно, по нажатию кнопки), он будет анимировать ImageView сверху вниз.

Посмотрите еще раз на официальный документ и попробуйте так.Если вы понимаете это однажды, на самом деле это довольно просто.Если у вас есть дополнительные вопросы или вы хотите, чтобы я привел вам лучший пример, просто спросите.

...