竖屏分割过渡效果(动画)

4
动画应该做以下事情:
  1. 将屏幕垂直分割成两部分。
  2. 上部向上移动。
  3. 下部向下移动。
  4. 最后,反方向。(关闭屏幕)

enter image description here

1个回答

12

这个想法非常简单:

  1. 将您的Activity A保存为位图
  2. 将位图分成两部分
  3. 使位图向外动画(向上和向下)

为了获得Activity的位图:

View root = currActivity.getWindow().getDecorView().findViewById(android.R.id.content);
root.setDrawingCacheEnabled(true);
Bitmap bmp = root.getDrawingCache();

为了分割位图:
int splitYCoord = (splitYCoord != -1 ? splitYCoord : bmp.getHeight() / 2);
if (splitYCoord > bmp.getHeight())
            throw new IllegalArgumentException("Split Y coordinate [" + splitYCoord + "] exceeds the activity's height [" + bmp.getHeight() + "]");
Bitmap mBmp1 = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), splitYCoord);
Bitmap mBmp2 = Bitmap.createBitmap(bmp, 0, splitYCoord, bmp.getWidth(), bmp.getHeight() - splitYCoord);
private static int[] mLoc1;
private static int[] mLoc2;
mLoc1 = new int[]{0, root.getTop()};
mLoc2 = new int[]{0, root.getTop() + splitYCoord};
private static ImageView mTopImage;
private static ImageView mBottomImage;
mTopImage = createImageView(destActivity, mBmp1, mLoc1);
mBottomImage = createImageView(destActivity, mBmp2, mLoc2);

private static ImageView createImageView(Activity destActivity, Bitmap bmp, int loc[]) {
    ImageView imageView = new ImageView(destActivity);
    imageView.setImageBitmap(bmp);

    WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
    windowParams.gravity = Gravity.TOP;
    windowParams.x = loc[0];
    windowParams.y = loc[1];
    windowParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    windowParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
    windowParams.flags =
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
    windowParams.format = PixelFormat.TRANSLUCENT;
    windowParams.windowAnimations = 0;
    destActivity.getWindowManager().addView(imageView, windowParams);

    return imageView;
}

在我们创建位图之后,应用动画

AnimatorSet mSetAnim = new AnimatorSet();
mTopImage.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mBottomImage.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mSetAnim.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        clean(destActivity);
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        clean(destActivity);
                    }
                        ...
                });

Animator anim1 = ObjectAnimator.ofFloat(mTopImage, "translationY", mTopImage.getHeight() * -1);
Animator anim2 = ObjectAnimator.ofFloat(mBottomImage, "translationY", mBottomImage.getHeight());

mSetAnim.setDuration(duration);
mSetAnim.playTogether(anim1, anim2);
mSetAnim.start();

private void clean(Activity activity) {
    if (mTopImage != null) {
        mTopImage.setLayerType(View.LAYER_TYPE_NONE, null);
        try {
            activity.getWindowManager().removeViewImmediate(mBottomImage);
        } catch (Exception ignored) {}
    }
    if (mBottomImage != null) {
        mBottomImage.setLayerType(View.LAYER_TYPE_NONE, null);
        try {
            activity.getWindowManager().removeViewImmediate(mTopImage);
        } catch (Exception ignored) {}
    }

    mBmp1 = null;
    mBmp2 = null;
}

以上代码仅供参考。您可以从以下链接中找到完整的演示。
参考链接:ActivitySplitAnimation

1
@Roylee 实际上,我们需要为降级版本编写自己的代码,因为在这段代码中,那个人使用了较高级别的Android API。 - user456118
@Abhan 关闭屏幕可以反转该过程吗? - Roy Lee
我在屏幕上使用TextureView时遇到了问题。绘制缓存位图返回的结果是透明的,而TextureView(显示视频)则无法正常显示... 有什么想法吗? - Amitay
1
@Roylee 最近有更新吗?答案看起来有些过时。我需要适用于API 17+的答案。 - Mangesh
我正在尝试做相反的事情...在按下返回按钮时,这两个部分会动画连接并打开ActivityA。我该如何着手处理? - Aman Verma
显示剩余2条评论

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