更改 android 视图的位置似乎会更改动画枢轴

Changing the position of an android view appears to change the animation pivot

我正在使用 Xamarin (C#),但 Java 解决方案很好。

我有一个自定义 parent 视图和一个 child 视图。 parent 具有固定的大小和位置,child 应该 扩展 到用户点击 parent 的视图中。 expand 动画是一个简单的淡入和缩放动画,应该围绕 child.

的中心旋转

我目前看到的结果是 child 总是在 parent 的 upper-left 角开始播放动画,并且似乎转换为用户点击的点适当缩放和褪色。这让我认为动画枢轴以某种方式受到干扰。

如何移动 child 元素并确保应用到它的动画仍然围绕局部中心点旋转,以及究竟是什么导致了我目前看到的这种行为?

编辑:我发现根本原因是动画缩放了 child 的 x 和 y 坐标及其宽度和高度,因此当scale 为 0 时,child 出现在 parent 元素的原点,当 scale 为 1 时,它出现在正确的位置。我现在的新问题是:我可以使用什么方法将 child 绝对定位在 parent 中而不受缩放的影响?

谢谢。

Parent 查看 Class

public class Parent: RelativeLayout
{
  private RelativeLayout _child;
  private Animation      _animation;
  private LayoutParams   _layoutParams;

  public Parent(Context context, IAttributeSet attrs)
    : base(context, attrs)
  {
    _layoutParams = new RelativeLayout.LayoutParams(64, 64);

    _child = new RelativeLayout(context);
    _child.LayoutParameters = _layoutParams;
    _child.SetBackgroundColor(Color.Red);
    _child.Visibility = ViewStates.Invisible;
    this.AddView(_child);

    _animation = AnimationUtils.LoadAnimation(context, Resource.Animation.Expand);
    _animation.AnimationEnd += OnAnimationEnd;

    this.Touch += OnTouch;
  }

  private void OnTouch(object sender, View.TouchEventArgs e)
  {
    // position the top left of the child view such that
    // the center point lies over the touch point
    var x = e.Event.GetX() - (_child.Width / 2);
    var y = e.Event.GetY() - (_child.Height / 2);
    _child.SetX(x);
    _child.SetY(y);

    _child.StartAnimation(_animation);
    _child.Visibility = ViewStates.Visible;
  }
}

展开动画资源

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:shareInterpolator="true"
    android:duration="500" >
  <scale
    android:fromXScale="0"
    android:fromYScale="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1"
    android:toYScale="1" >
  </scale>
  <alpha
    android:fromAlpha="0"
    android:toAlpha="1" />
</set>

我现在可以使用此动画,尽管新方法与其说是解决方案,不如说是一种变通方法。

通过以编程方式创建动画并将枢轴绝对设置在父级内,我能够确保子位置和枢轴每次都完美对齐:

private void OnTouch(object sender, View.TouchEventArgs e)
  {
    // position the top left of the child view such that
    // the center point lies over the touch point
    var x = e.Event.GetX() - (_child.Width / 2);
    var y = e.Event.GetY() - (_child.Height / 2);
    _child.SetX(x);
    _child.SetY(y);

    // define the animation with the pivot absolutely positioned over the center of the child
    var animation = new AnimationSet(true);
    animation.Interpolator = new DecelerateInterpolator();
    animation.Duration = 500;
    animation.AddAnimation(new AlphaAnimation(0.4F, 0F));
    animation.AddAnimation(new ScaleAnimation(0F, 4F, 0F, 4F,
      Dimension.Absolute, x,
      Dimension.Absolute, y));

    _child.StartAnimation(animation);
    _child.Visibility = ViewStates.Visible;
  }

如果有一种解决方案允许使用动画资源并且不需要绝对值,那么会更加简洁。