Shared element transition flicker when using Dialo

2019-05-31 19:52发布

Update:

There's a repro at https://github.com/ulyssesp/SharedElementTransitions.

This only happens when there's a DialogFragment that holds the transitioning ImageView, and it only happens sometimes. When it does happen, if the image is off the bottom of the DialogFragment but still visible, then you can see part of the image being rendered correctly. It feels like it's a race condition where the DialogFragment gets rendered after (and therefore on top of) the ImageView.


I'm trying to use a shared element transition from an ImageView in a ScrollView on a DialogFragment using Picasso and a cache to load the image. Every once in a while when the ScrollView is scrolled, there is a flicker when entering the transition.

https://drive.google.com/file/d/0B9K_Hjcu9iFOV3lYNVB1UlpsNTQ/view?usp=sharing

The last click on the video file above best shows what I'm talking about. Note that the flicker doesn't happen every time, and the scroll view has to be scrolled for the flicker to occur. There are a lot more things happening in the real project, but this is a minimal sample project to reproduce the bug.

Relevant code:

styles.xml:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowSharedElementReenterTransition">@null</item>
    <item name="android:windowSharedElementExitTransition">@null</item>
</style>

ImageFragment::onCreateView:

...

mImageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ActivityOptions activityOptions =
            ActivityOptions.makeSceneTransitionAnimation(getActivity(), v, "image");

        Intent i = new Intent(getActivity(), ImageDisplayActivity.class);
        i.putExtra("url", "http://i.imgur.com/DvpvklR.png");
        getActivity().startActivity(i, activityOptions.toBundle());
    }
});

new Picasso.Builder(getActivity())
    .memoryCache(MainActivity.sCache)
    .build()
    .load("http://i.imgur.com/DvpvklR.png")
    .into(mImageView);

...

ImageDisplayActivity:

...

mImageView.setImageBitmap(MainActivity.sCache.get(getIntent().getStringExtra("url") + "\n"));

If you have any insights or need more information, let me know!

1条回答
Rolldiameter
2楼-- · 2019-05-31 20:12

This looks like a bug in the Activity Transitions. Even though there is no shared element exit transition and no exit transition, we move the shared elements into the Window's root overlay. Normally this is not a problem, but because DialogFragment creates a dialog, which creates a new window, the shared element moves from the dialog's window into the Activity's window! you can see the shared element pop below the dialog temporarily and then rise above once the started Activity takes it.

It would be ideal to be able to fix this by moving shared elements to the correct overlay, not just the Activity Window's overlay. That way if you share elements from the dialog AND the activity's windows, they all appear in the right place.

For now, though, this is not going to work. Sorry.

查看更多
登录 后发表回答