将视图从一种布局动画化为另一种布局 [英] Animate a view from one Layout to other Layout
问题描述
检查所附图像以方便说明。
Check attached image for easy explanation.
翻译动画有效,但会在同一视图内设置动画。
我希望视图从一种布局飞出到另一种布局。
Translate animation works but it animates inside the same view. I want view to fly out from one layout to other.
我在这里尝试了另一个答案。 (使用相同布局的动画)
I tried this from another answer here. (Animates in same layout)
public class Animations {
public Animation fromAtoB(float fromX, float fromY, float toX, float toY, int speed){
Animation fromAtoB = new TranslateAnimation(
Animation.ABSOLUTE, //from xType
fromX,
Animation.ABSOLUTE, //to xType
toX,
Animation.ABSOLUTE, //from yType
fromY,
Animation.ABSOLUTE, //to yType
toY
);
fromAtoB.setDuration(speed);
fromAtoB.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
return fromAtoB;
}
推荐答案
我最近做了一个动画使用Animators的类似类型。通常,视图不会显示在其父母的边界之外,而会被其父母的边界所切断。因此,诀窍在于将一个新视图(shuttleView)放置在您要对其进行动画处理的原始视图(fromView)的顶部,将它们对齐,然后将ShuttleView的缩放/平移动画化为目标视图(toView)。
I recently did animation of a similar kind using Animators. In general, views will not display themselves outside of their parents' boundaries, the view will be cut by it's parent's boundaries. That's why, the trick is to place a new view (shuttleView) on top of the origin view (fromView) that you want to animate, align them, and animate scaling/translation of shuttleView into a target view (toView).
此解决方案支持缩放和转换,此处为示例: https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0
This solution supports both scaling and translation, here is sample: https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0
以下是代码:
activity_main.xml
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentTop="true"
android:background="@android:color/holo_blue_dark">
<TextView
android:id="@+id/itemTo"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="10dp"
android:background="@android:color/holo_blue_bright"
android:text="to"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:background="@android:color/holo_blue_dark">
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="@android:color/holo_blue_bright" />
<TextView
android:id="@+id/itemFrom"
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:text="from"
android:background="@android:color/holo_blue_bright" />
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="@android:color/holo_blue_bright" />
</LinearLayout>
<View
android:id="@+id/shuttle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_bright"/>
活动类别:
public class MainActivity extends AppCompatActivity {
public static final int ANIMATION_SPEED = 3000;
private RelativeLayout rootView;
private View fromView, toView, shuttleView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootView = (RelativeLayout) findViewById(R.id.rootView);
fromView = findViewById(R.id.itemFrom);
toView = findViewById(R.id.itemTo);
shuttleView = findViewById(R.id.shuttle);
fromView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Rect fromRect = new Rect();
Rect toRect = new Rect();
fromView.getGlobalVisibleRect(fromRect);
toView.getGlobalVisibleRect(toRect);
AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, shuttleView, fromRect, toRect, ANIMATION_SPEED, 0);
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
shuttleView.setVisibility(View.VISIBLE);
fromView.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
shuttleView.setVisibility(View.GONE);
fromView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
});
}
public static AnimatorSet getViewToViewScalingAnimator(final RelativeLayout parentView,
final View viewToAnimate,
final Rect fromViewRect,
final Rect toViewRect,
final long duration,
final long startDelay) {
// get all coordinates at once
final Rect parentViewRect = new Rect(), viewToAnimateRect = new Rect();
parentView.getGlobalVisibleRect(parentViewRect);
viewToAnimate.getGlobalVisibleRect(viewToAnimateRect);
viewToAnimate.setScaleX(1f);
viewToAnimate.setScaleY(1f);
// rescaling of the object on X-axis
final ValueAnimator valueAnimatorWidth = ValueAnimator.ofInt(fromViewRect.width(), toViewRect.width());
valueAnimatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newWidth = (int) valueAnimatorWidth.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.width = newWidth;
viewToAnimate.setLayoutParams(lp);
}
});
// rescaling of the object on Y-axis
final ValueAnimator valueAnimatorHeight = ValueAnimator.ofInt(fromViewRect.height(), toViewRect.height());
valueAnimatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newHeight = (int) valueAnimatorHeight.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.height = newHeight;
viewToAnimate.setLayoutParams(lp);
}
});
// moving of the object on X-axis
ObjectAnimator translateAnimatorX = ObjectAnimator.ofFloat(viewToAnimate, "X", fromViewRect.left - parentViewRect.left, toViewRect.left - parentViewRect.left);
// moving of the object on Y-axis
ObjectAnimator translateAnimatorY = ObjectAnimator.ofFloat(viewToAnimate, "Y", fromViewRect.top - parentViewRect.top, toViewRect.top - parentViewRect.top);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setInterpolator(new DecelerateInterpolator(1f));
animatorSet.setDuration(duration); // can be decoupled for each animator separately
animatorSet.setStartDelay(startDelay); // can be decoupled for each animator separately
animatorSet.playTogether(valueAnimatorWidth, valueAnimatorHeight, translateAnimatorX, translateAnimatorY);
return animatorSet;
}
}
您可以在以下方面进行大量定制animatorSet侦听器中动画的不同阶段出现和消失的内容。希望对您有所帮助。
You can do a whole bunch of customizations in terms of what appears and disappears at different stages of animation in animatorSet listener. Hope it's helpful.
这篇关于将视图从一种布局动画化为另一种布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!