Android reverse shared element transition on back after orientation change?

前端 未结 4 1403
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-31 14:20

For shared element transition I am following this github project. It has 2 screens - one with recyclerview having number of cards & second the detail screen. As expected

相关标签:
4条回答
  • 2020-12-31 14:46

    I came across this same problem and this how I fixed it.

    When the RecyclerView item is clicked, I pass the current position:

    @Override
    public void onItemClick(View sharedView, String transitionName, int position) {
        viewPosition = position;
        Intent intent = new Intent(this, TransitionActivity.class);
        intent.putExtra("transition", transitionName);
        ActivityOptionsCompat options = ActivityOptionsCompat.
                makeSceneTransitionAnimation(this, sharedView, transitionName);
        ActivityCompat.startActivity(this, intent, options.toBundle());
    }
    

    I save it in onSaveInstanceState to persist across configuration changes:

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(VIEW_POSITION, viewPosition);
    }
    

    Then, in the onCreate method:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Workaround for orientation change issue
        if (savedInstanceState != null) {
            viewPosition = savedInstanceState.getInt(VIEW_POSITION);
        }
    
        setExitSharedElementCallback(new SharedElementCallback() {
            @Override
            public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
                super.onMapSharedElements(names, sharedElements);
                if (sharedElements.isEmpty()) {
                    View view = recyclerView.getLayoutManager().findViewByPosition(viewPosition);
                    if (view != null) {
                        sharedElements.put(names.get(0), view);
                    }
                }
            }
        });
    }
    

    Cause of the problem: the sharedElements map was empty (I don't know why) after the orientation change.

    0 讨论(0)
  • 2020-12-31 14:56

    At last, I could fix this by applying separate theme to detail screen overriding following attribute value, but not sure why did this parameter change the animation behavior.

    <item name="android:windowIsTranslucent">true</item>
    
    0 讨论(0)
  • 2020-12-31 14:58

    If you go into "Developer options" and enable "Don't keep activities", I think you'll find the problem will occur as well. In other words, the problem isn't that you are rotating the device... but more generally that the first activity is being destroyed while in the background.

    Looking at your sample code, it looks like you're doing some weird stuff with an adapter (i.e. feeding the recycler view new grid items every 50ms from a background thread)? I can see why that might cause some issues for you... for example, what if the calling activity is destroyed and needs to be recreated immediately after the user clicks the back button and the return transition begins? If the shared element return transition begins and the desired shared element does not yet exist in the first activity (for example, because it has not yet been added by the adapter yet), the transition will not work properly.

    I think this should probably be enough information to get you started solving the problem.

    0 讨论(0)
  • 2020-12-31 15:05

    You have to set:

    requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    requestWindowFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
    

    in the calling and the called activity (MainActivity + NextActivity in this example).

    I assume you open the NextActivity by calling:

    ActivityOptions options = ActivityOptions.
          makeSceneTransitionAnimation(this, new Pair<View, String>(viewToAnimate, "animationName"));
    Intent intent = new Intent(MainActivity.this, NextActivity.class);
    startActivity(intent, options.toBundle());
    

    In the NextActivity you have to add:

    animatingView.setTransitionName("animationName");
    

    If you do this the transition will work if you tap the back button.

    BUT if you turn the device and press the back button it won't work.

    To solve this problem i added this in the first activity (MainActivity in this example):

    animatingView.setTransitionName("animationName");
    

    The system now knows what to animate after a screen rotation.

    0 讨论(0)
提交回复
热议问题