改变安卓视图的位置似乎会改变动画中心点

4

我目前在使用Xamarin(C#)进行开发,但Java解决方案也可以。

我的一个自定义父视图包含一个子视图。父视图具有固定的大小和位置,子视图应该在用户点击父视图处展开以显示出来。反应展开动画是一个简单的淡入淡出和缩放,应该围绕子元素中心旋转。

我当前看到的结果是,子元素总是从父元素的左上角开始动画,似乎沿着适当的比例尺度和淡化效果向用户点击的点移动。这让我想到动画枢轴受到了干扰。

我该如何移动子元素并确保仍然围绕本地中心点进行动画,以及到底是什么原因导致了我当前看到的行为?

编辑:我已经发现导致这种行为的根本原因是动画也会缩放子元素的x和y坐标以及宽度和高度,因此当缩放为0时,子元素出现在父元素的原点,当缩放为1时,它才出现在正确的位置。我的新问题是:我可以使用哪种方法将子元素绝对定位在父元素中,而不受缩放的影响?

谢谢。

父视图类

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>

这是答案:https://dev59.com/QGw05IYBdhLWcg3wXQsg#73496792 - John T
1个回答

0

我现在已经让这个动画工作了,虽然新的方法更像是一种变通而不是解决方案。

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

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;
  }

如果有一种解决方案可以使用动画资源而不需要绝对值,那将会更加简洁。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接