简体   繁体   English

从其他视图的位置对视图进行动画处理/翻译

[英]Animate/translate view from position of other view

I have a fab and a framelayout which can host a fragment. 我有一个晶圆厂和可以容纳一个片段的框架布局。

I'm trying to do a translation animation so that my framelayout starts at the position of the fab and ends up at its original position. 我正在尝试制作翻译动画,以使我的框架布局从晶圆厂的位置开始,并在其原始位置结束。 (complex layout, the fab is in another xml file but <include> in same layout as the frame) So basically step 2 here: How to transform a FAB into a popup menu? (复杂布局,晶圆厂位于另一个xml文件中,但<include>与框架位于相同的布局中)因此,这里的基本步骤2: 如何将FAB转换为弹出菜单?

I have tried: 我努力了:

<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" />

and

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

with

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

So I tried with the values I get from these methods 所以我尝试了从这些方法获得的值

myFab.getLocationOnScreen()
myFab.getLocationInWindow()

Both methods give (891, 1130) . 两种方法都给出(891, 1130) I've tried plugging those in or converting it to dp, that gets it closer(not very close still though). 我试过将它们插入或将其转换为dp,这会使它更接近(尽管不是很接近)。

Another strange thing is that I thought if I used absolute values in the animation I thought zero would be top left of the screen but it isn't. 另一个奇怪的事情是,我认为如果我在动画中使用绝对值,我会认为零将位于屏幕的左上方,但事实并非如此。 x: 0 y: 0 give me the same results as 0%,0% and 0%p,0%p . x: 0 y: 0给我与0%,0%0%p,0%p相同的结果。 they all animate the view to the top left point of where the framelayout is in constrained to in the xml 它们都将视图动画化为xml中framelayout约束的左上角

How do I translate a view from another view to 'itself'? 如何将一个视图从另一个视图转换为“自身”?

Use ConstraintLayout for your layout, put your view constraints to starting position (here I will animate @+id/view after clicking @+id/fab . Animated view has to be VISIBLE or INVISIBLE - GONE will mess up animation. 使用ConstraintLayout进行布局,将视图约束放置到起始位置(这里,我将在单击@+id/fab后对@+id/view进行动画处理。动画视图必须是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>

There are few options: 有几种选择:

  1. Use ObjectAnimator 使用ObjectAnimator

In your xml file put View that will be animated on fab position: 在您的xml文件中,放置将在fab位置上动画的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. Or use ViewPropertyAnimator (same XML as above) 或使用ViewPropertyAnimator(与上述XML相同)

      fab.setOnClickListener { view.animate() .x(0f) .y(0f) .setDuration(2000L) .start() } 
  2. Or use TransitionManager, MotionLayout, scene api or animate ConstraintSet manually. 或手动使用TransitionManager,MotionLayout,场景api或为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) } 

This approach will allow to specify start state as xml layout and end state as xml layout, but you will have less control. 这种方法将允许将开始状态指定为xml布局,将结束状态指定为xml布局,但是您的控制较少。

With other view position: 与其他视图位置:

        fab.setOnClickListener {
            view.animate()
                .x(fab.left.toFloat())
                .y(fab.top.toFloat())
                .setDuration(2000L)
                .start()
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM