基本上,我正在尝试在两个片段之间进行ImageView的共享元素转换。我的最终目标是拥有一个看起来非常类似于默认图库的动画。重要的一点是,我正在使用Glide加载我的图像。我遇到的问题是我无法使scaleType平滑地动画化(从centerCrop到fitCenter)。 我有一个包含RecyclerView的片段,其项每个包含一个ImageView。这些ImageView旨在成为缩略图,XML如下:
<ImageView
android:id="@+id/ivPhoto"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/large_spacing"
android:scaleType="centerCrop"/>
重要/有问题的部分是
scaleType="centerCrop"
我使用以下方式在RecyclerView适配器中设置转换名称并加载图像:holder.ivPhoto.setTransitionName(current.getPhotoFilepath());
Glide.with(holder.ivPhoto.getContext())
.load(current.getPhotoFilepath())
.dontTransform()
.into(holder.ivPhoto);
当一个项目被点击时,将运行以下代码:
@Override
public void onItemClicked(AssetDetail assetDetail, ImageView imageView) {
if (assetDetail.getPhotoFilepath() != null) {
AssetDetailFragmentDirections.ActionAssetDetailFragmentToDisplayImageFragment action = AssetDetailFragmentDirections.actionAssetDetailFragmentToDisplayImageFragment(assetDetail.getPhotoFilepath());
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder()
.addSharedElement(imageView, assetDetail.getPhotoFilepath())
.build();
NavHostFragment.findNavController(this).navigate(action, extras);
}
}
这将带您到第二个片段,其基本上只包含以下ImageView(技术上是PhotoView,我也尝试过使用普通的ImageView):
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/ivImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
我推迟进入转换并设置我想要使用的转换:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
TransitionSet transitionSet = new TransitionSet()
.addTransition(new ChangeBounds())
.addTransition(new ChangeImageTransform())
.setDuration(1500)
.setOrdering(TransitionSet.ORDERING_TOGETHER)
.setInterpolator(new FastOutSlowInInterpolator());
setSharedElementEnterTransition(transitionSet);
}
最后,我获取并设置了过渡名称,加载图像并启动延迟的进入过渡:
DisplayImageFragmentArgs args = DisplayImageFragmentArgs.fromBundle(getArguments());
binding.ivImage.setTransitionName(args.getImageFilepath());
Glide.with(requireContext())
.load(args.getImageFilepath())
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
startPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
startPostponedEnterTransition();
return false;
}
})
.dontTransform()
.into(binding.ivImage);
这导致该动画完全错误。
如果我像这样交换转换顺序:
TransitionSet transitionSet = new TransitionSet()
.addTransition(new ChangeImageTransform())
.addTransition(new ChangeBounds())
.setDuration(1500)
.setOrdering(TransitionSet.ORDERING_TOGETHER)
.setInterpolator(new FastOutSlowInInterpolator());
我理解这句话的意思是:“我找到了更接近的动画this animation,但进入过渡效果从一个奇怪的位置开始,而返回过渡效果在包含ImageView的CardView之后/内部。”第二段话的意思是:“根据this article尝试一些不同的过渡效果。”
TransitionSet transitionSet = new TransitionSet()
.addTransition(new ChangeClipBounds())
.addTransition(new ChangeTransform())
.addTransition(new ChangeBounds())
.setDuration(1500)
.setOrdering(TransitionSet.ORDERING_TOGETHER)
.setInterpolator(new FastOutSlowInInterpolator());
在this中,您可以看到scaleType立即更改,然后其他动画发生。我希望scaleType的更改与其他内容一起平滑地进行动画处理。
有趣的是,在RecyclerView中的ImageView中删除scaleType="centerCrop"
后,最终过渡的组合就会完美地进行动画处理,但显然这意味着图像具有其原始宽高比,而不是适当的缩略图。请参见此处。
问题显然与scaleType有关,但无论我尝试什么,都似乎无法使其正常工作。我已经做了大量的谷歌搜索和阅读,但没有找到解决问题的方法。
据我所了解,使用ChangeImageTransform应该可以动画化scaleType,但是使用任何我尝试过的组合(包括与ChangeTransform一起尝试)似乎都无法正常工作,或者至少不是我想要/期望的方式。我已经超出了沮丧的程度。
如果有人能给我任何帮助来解决这个问题,我将非常感激。