具有 scaleType centerCrop 过渡的共享元素是跳跃的 [英] Shared Element with scaleType centerCrop transition is jumpy

查看:29
本文介绍了具有 scaleType centerCrop 过渡的共享元素是跳跃的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当 2 个 ImageViews 从一个屏幕转到下一个屏幕时,我正在尝试实现共享元素转换.其中一张图像在两个屏幕上的 scaleType 都是 centerCrop.我面临的问题是,当过渡开始时,图像会在将其动画到下一个屏幕之前恢复到原始大小(裁剪前).当它到达下一个屏幕时,它以原始大小到达它,然后才将其裁剪到目标图像视图.

I'm trying to implement a shared elements transition when 2 ImageViews from one screen go to the next screen. one of the images has a scaleType of centerCrop on both screen. The problem I'm facing is that when the transition starts the image is going to it's original size (before the crop) just before the animating it to the next screen. when it's reaches the next screen it reaches it with it's original size and only then it's cropped to the target image view.

整个体验并不流畅,而且真的让人眼花缭乱.我使用的代码是:

The whole experience is not smooth and really jumpy to the eye. The code I use is:

public void animateIntent(View view, ArticleCoverData articleCoverData) {
    Intent intent = new Intent(mActivity, ReaderActivity.class);
    intent.putExtra(Constants.ARTICLE_DATA, articleCoverData);

    // The view animation will start from
    View coverStartView = view.findViewById(R.id.coverImage);
    View coverDiagonalDecoratorStartView = view.findViewById(R.id.diagonal_image_decorator);

    Pair<View, String> pair1 = Pair.create(coverStartView, mActivity.getString(R.string.transition_timeline_cover_image_to_reader_name));
    Pair<View, String> pair2 = Pair.create(coverDiagonalDecoratorStartView, mActivity.getString(R.string.transition_timeline_cover_image_diagonal_decorator_to_reader_name));

    ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(mActivity, pair1, pair2);
    ActivityCompat.startActivity(mActivity, intent, options.toBundle());
}

图像是使用 Glide 从网络加载的,代码如下:

The image is loaded from the web using Glide with following code:

Glide.with(mActivity).load(articleCoverData.mImageUrl).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.SOURCE).dontTransform().into(holder.coverImage);

在接收端,图片加载如下:

On the receiving side the image is loaded as follows:

Glide.with(mContext).load(mData.mImageUrl).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.SOURCE).into(mCoverImageView);

在我定义的样式中:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Add this line -->
    <item name="android:windowContentTransitions">true</item>

    <!-- This is the color of the Status bar -->
    <item name="colorPrimaryDark">@color/transparent</item>

    <!-- specify shared element transitions -->
    <item name="android:windowSharedElementEnterTransition">
        @transition/change_image_transform</item>
    <item name="android:windowSharedElementExitTransition">
        @transition/change_image_transform</item>
</style>

change_image_transform 是:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeImageTransform/>
</transitionSet>

尝试将过渡更改为:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds/>
    <changeTransform/>
    <changeImageTransform/>
</transitionSet>

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds/>
    <changeImageTransform/>
</transitionSet>

但结果是一样的.

问题是:我是否在这里遗漏了一些东西,我还需要做些什么来使这种体验更加窒息?或者这是一个 Android 错误?

The question is: Am I missing something here, is there something else I need to do to make this experience smother? or this is an Android bug?

推荐答案

最后,设法解决了这个问题.使用以下代码和配置实现了预期的结果:

Finally, managed to solve this issue. desired result was achieved using the following code and configuration:

private static void startAnimatedTransitionIntent(Activity context, View view, ArticleCoverData articleCoverData) {
    Intent intent = new Intent(context, ReaderActivity.class);
    intent.putExtra(Constants.ARTICLE_DATA, articleCoverData);

    View coverStartView = view.findViewById(R.id.coverImage);
    View coverDiagonalDecoratorStartView = view.findViewById(R.id.diagonal_image_decorator);

    Window window = context.getWindow();
    View decor = window.getDecorView();
    View navigationBarStartView = decor.findViewById(android.R.id.navigationBarBackground);

    List<Pair<View, String>> pairs = new ArrayList<>();
    pairs.add(Pair.create(coverStartView, context.getString(R.string.transition_timeline_cover_image_to_reader_name)));
    pairs.add(Pair.create(coverDiagonalDecoratorStartView, context.getString(R.string.transition_timeline_cover_image_diagonal_decorator_to_reader_name)));

    if (navigationBarStartView != null) {
        pairs.add(Pair.create(navigationBarStartView, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
    }

    ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(context, pairs.toArray(new Pair[pairs.size()]));
    ActivityCompat.startActivity(context, intent, options.toBundle());
}

我正在使用 Picasso 和以下代码将图像加载到图像视图中:

I'm loading the images into the image view using Picasso and the following code:

Picasso.with(mActivity).load(articleCoverData.mImageUrl).into(articleVH.coverImage);

在接收方,我以相同的方式应用图像:

On the receiving side I apply the image in the same way:

Picasso.with(mContext).load(mData.mImageUrl).into(mCoverImageView);

风格:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:statusBarColor">@color/app_red</item>
    <item name="android:windowContentTransitions">true</item>

    <!-- This is the color of the Status bar -->
    <item name="colorPrimaryDark">@color/transparent</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>

    <!--<item name="android:windowEnterTransition">@transition/cheeses_enter</item>-->
    <!--<item name="android:windowExitTransition">@transition/cheeses_exit</item>-->

    <item name="android:windowSharedElementEnterTransition">@transition/cheeses_enter</item>
    <item name="android:windowSharedElementExitTransition">@transition/cheeses_exit</item>
</style>

两个转换:cheeses_entercheeses_exit 是:

both transitions: cheeses_enter and cheeses_exit are:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
    <changeBounds />
    <changeTransform />
    <changeClipBounds />
    <changeImageTransform />
</transitionSet>

重要的是使用 ImageView scaleType 参数应用您的比例类型,而不是使用 Picasso 裁剪或 Glide 裁剪.

The important thing is to apply your scale type using the ImageView scaleType parameter and not using Picasso crop or Glide crop.

因为如果您这样做,裁剪和取消裁剪操作将作为过渡的一部分执行.

Because if you do that the the crop and the un-crop action would perform as part of the transition.

这篇关于具有 scaleType centerCrop 过渡的共享元素是跳跃的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆