Анимировать / перевести вид с позиции другого вида - PullRequest
1 голос
/ 25 марта 2019

У меня есть потрясающий и framelayout, который может содержать фрагмент.

Я пытаюсь сделать анимацию перевода так, чтобы моя разметка кадра начиналась с позиции fab и заканчивалась в ее исходном положении. (сложный макет, потрясающий файл находится в другом XML-файле, но <include> в том же макете, что и фрейм) Итак, в основном шаг 2 здесь: Как преобразовать FAB во всплывающее меню?

Я пробовал:

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="340"
    android:fromYDelta="431"
    android:toXDelta="0"
    android:toYDelta="0"
    android:duration="1000"
    android:fillAfter="true" />

и

val anim = TranslateAnimation(340f, 0f, 431f, 0f)

с

 myFab.setOnClickListener {
    val frame = my_frame_im_about_to_fill_with_a_fragment
    frame.startAnimation(anim)
 }

Итак, я попытался использовать значения, полученные этими методами

myFab.getLocationOnScreen()
myFab.getLocationInWindow()

Оба метода дают (891, 1130). Я попытался подключить их или преобразовать в dp, что приближает их (хотя и не очень близко).

Еще одна странная вещь: я подумал, что если бы я использовал абсолютные значения в анимации, я думал, что ноль будет в верхнем левом углу экрана, но это не так. x: 0 y: 0 дает мне те же результаты, что и 0%,0% и 0%p,0%p. все они анимируют вид на верхнюю левую точку, где находится ограничение кадра в xml

Как мне перевести вид из другого вида в «сам»?

1 Ответ

1 голос
/ 26 марта 2019

Используйте ConstraintLayout для своего макета, установите ограничения вида в начальную позицию (здесь я буду анимировать @+id/view после нажатия @+id/fab. Анимированный вид должен быть VISIBLE или INVISIBLE - GONE испортит анимацию .

    <androidx.constraintlayout.widget.ConstraintLayout
             /*constraint stuff*/>       
                <View
                    android:id="@+id/view"
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:visibility="invisible"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent" />

                <com.google.android.material.floatingactionbutton.FloatingActionButton
                    android:id="@+id/fab"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="8dp"
                    android:layout_marginBottom="120dp"
                    app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
                    app:layout_constraintEnd_toEndOf="@+id/symbolList" />

   </androidx.constraintlayout.widget.ConstraintLayout>

Есть несколько вариантов:

  1. Использовать ObjectAnimator

В ваш XML-файл поместите View, который будет анимирован в потрясающей позиции:

view = findViewById(R.id.view)
fab = findViewById(R.id.fab)

fab.setOnClickListener {

    view.visibility = View.VISIBLE
    val propertyX = PropertyValuesHolder.ofFloat(View.X, 0f)
    val propertyY = PropertyValuesHolder.ofFloat(View.Y, 0f)
    ObjectAnimator.ofPropertyValuesHolder(view, propertyX, propertyY).apply {
        duration = 2000L
        start()
    }
}
  1. Или используйте ViewPropertyAnimator (тот же XML, что и выше)

        fab.setOnClickListener {
          view.animate()
                .x(0f)
                .y(0f)
                .setDuration(2000L)
                .start()
        }
    
  2. Или используйте TransitionManager, MotionLayout, api scene или анимируйте ConstraintSet вручную.

    private fun startAnimation() {
    
    val animationEndConstraints = ConstraintSet().apply {
        clone(container)
        clear(button.id, ConstraintSet.START)
        clear(button.id, ConstraintSet.TOP)
        // instead of parent you can use fab.id
        connect(button.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0)
        connect(button.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
    }
    TransitionManager.beginDelayedTransition(container)
    animationEndConstraints.applyTo(container)
    }
    

Этот подход позволит указать начальное состояние как макет xml и конечное состояние как макет xml, но у вас будет меньше контроля.

С другой позицией просмотра:

        fab.setOnClickListener {
            view.animate()
                .x(fab.left.toFloat())
                .y(fab.top.toFloat())
                .setDuration(2000L)
                .start()
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...