如何将视图缩小并滑入左上角?

How Do I Shrink and Slide a View into the Upper-Left Corner?

我有一个布局资源文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <!-- other widget here -->

  <ImageView
    android:id="@+id/thumbnail"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFFFF"
    android:layout_gravity="top|left"
    android:visibility="gone"/>

</FrameLayout>

在某个时间点,这个布局会显示在我的activity中。那时,我将 thumbnail ImageView 的可见性设置为 View.VISIBLE,然后我想将其设置为动画以占据屏幕 width/height 的 30% ,位于左上角 marginPixels(在我的测试设备上,marginPixels 是 48)。这将暴露底层 View,除了被 thumbnail.

接管的部分

为此,我有以下 Java:

thumbnail.setVisibility(View.VISIBLE);
thumbnail
  .animate()
  .scaleX(0.3f)
  .scaleY(0.3f)
  .x(marginPixels)
  .y(marginPixels)
  .setDuration(animDuration);

结果是动画发生了,但是 thumbnail 位于 FrameLayout 的中心。

我试过:

None好像有效果。 thumbnail 始终居中。如果我注释掉 x()y() 调用,结果也会居中,表明由于某种原因,它们被忽略了。相反,如果我注释掉 scaleX()scaleY() 调用(保留 x()y(),如原始清单中所示),thumbnail 将转换为正确的位置,但它仍然是全尺寸的。如果我在动画之前在 thumbnail 本身上使用 setX()setY() 并注释掉 x()y() 调用,则 thumbnail 最初是位于正确的位置,但一旦缩放动画开始,我又回到了居中。

现在,我当然可以计算出要使用的正确值,给定屏幕尺寸等等。但似乎 x()/y() 应该是在 ViewPropertyAnimator 上使用的正确方法,所以我想弄清楚我哪里出错了。

更新:此代码有效(或至少接近 - 我尚未实际测量结果以确认精确的像素位置):

int x=(int)(-0.35f*(float)bmp.getWidth())+marginPixels;
int y=(int)(-0.35f*(float)bmp.getHeight())+marginPixels;

thumbnail.setVisibility(View.VISIBLE);
thumbnail.setImageBitmap(bmp);
thumbnail
  .animate()
  .x(x)
  .y(y)
  .scaleX(0.3f)
  .scaleY(0.3f)
  .setDuration(animDuration);

我不明白为什么需要这些计算。 IOW,为什么 xy 取决于规模?

设置 scale 时(使用 setScale 或通过动画),将考虑 pivot 值。 pivotXpivotY 的默认值分别是 widthheight 的一半(分别)。因此,当 scale1.0f 时,任何使用默认 pivots 的缩放都会导致 View 从(或朝向)View 的中心缩放。 31=]

XY(以及 translationXtranslationY)不受 pivots 影响。您可以看到 thumbnail 实际上被移动了 marginPixels(垂直和水平)。

如果您尝试以下代码,您会发现一切都按预期工作。

thumbnail.setVisibility(View.VISIBLE);
thumbnail.setPivotX(0);
thumbnail.setPivotY(0);
thumbnail
  .animate()
  .scaleX(0.3f)
  .scaleY(0.3f)
  .x(marginPixels)
  .y(marginPixels)
  .setDuration(animDuration);