【问题标题】:How to know when Shared Element Transition ends如何知道共享元素转换何时结束
【发布时间】:2015-11-10 23:39:09
【问题描述】:

我在活动之间使用Shared Element Transitions。过渡效果很好,但我想知道共享元素过渡何时结束,以便显示其他内容。

我尝试在要转换到的活动中使用 SharedElementCallback 中的 onSharedElementEnd,但在转换开始之前会调用它。

还有其他我可以监听的回调吗?

【问题讨论】:

    标签: android shared-element-transition


    【解决方案1】:

    您是否尝试将动画侦听器绑定到onMapSharedElements 内的共享元素视图? ViewCompat.animate(view) 会给你一个新的或缓存的ViewPropertyAnimator(Compat),然后绑定动画监听器应该很简单。不过我没试过。

    setEnterSharedElementCallback(new SharedElementCallback() {
                @Override
                public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
                    super.onMapSharedElements(names, sharedElements);
                    View keySharedElementView = sharedElements.get("keySharedElement");
                    if(keySharedElementView != null){
                        ViewCompat.animate(keySharedElementView).setListener(new ViewPropertyAnimatorListenerAdapter(){
                            @Override
                            public void onAnimationEnd(View view) {
                                super.onAnimationEnd(view);
                            }
                        });
                    }
                }
            });
    

    Transition.Listener 添加到共享元素过渡效果如何?

     Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();
     sharedElementEnterTransition.addListener(new TransitionListenerAdapter() {
             @Override
              public void onTransitionEnd(android.support.transition.Transition transition) {
                        super.onTransitionEnd(transition);
               }
          });
    

    【讨论】:

    • 对于其他想知道的人来说,TransitionListenerAdapter 只是Transition.TransitionListener 接口的一个空实现。它可能取自@alex-lockwood 的公共项目:github.com/alexjlockwood/activity-transitions/blob/master/app/…
    • @gnuf 接口的适配器只是为了让你只实现你需要的方法。这对于 android sdk 和 java 中的所有侦听器适配器都是通用的。这将使您的代码保持干净整洁。
    • 片段呢?两种解决方案都不适合我
    • @HugoGresse 这是个好问题。我希望有人确认这种奇怪的行为:简单的转换,fragmentA 到 fragmentB (v4)。我只想知道过渡何时结束。所以我在 fragmentB 中放置了一个监听器,例如:((Transition) getSharedElementEnterTransition()).addListener(),它永远不会被调用。但!如果我还在 fragmentA 中的同一个转换中添加了一个空侦听器,那么两个侦听器都开始工作¯_(ツ)_/¯。这是一个简单的演示:github.com/Ghedeon/TransitionBug
    • @Ghedeon 你试过在片段B的“onAttach()”中调用“addListener()”吗?喜欢这里:github.com/google/iosched/blob/…
    【解决方案2】:

    请尝试onEnterAnimationComplete() 回调您的活动。

    我敢打赌,这正是您要找的。​​p>

     @Override
        public void onEnterAnimationComplete() {
            super.onEnterAnimationComplete();
    
        //your code 
        }
    

    【讨论】:

    • 看起来不错,但是有没有关于如何将它与片段转换一起使用的建议?
    • 怎么用?我不知道
    • 此解决方案有效,直到您发现该方法没有在低于 kitkat 的 api 级别中被调用,预计这将通过支持活动调用。无论如何都是比所有其他方法更好的选择
    • 请注意,这被称为共享元素转换完成之前。
    • 这对我来说效果不佳。叫得太早了。添加日志,你会看到。有效的是getWindow().getSharedElementEnterTransition().addListener()
    【解决方案3】:

    这是我在片段中所做的:

    Transition sharedElementEnterTransition = getActivity().getWindow().getSharedElementEnterTransition();
        sharedElementEnterTransition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
    
            }
    
            @Override
            public void onTransitionEnd(Transition transition) {
    
            }
    
            @Override
            public void onTransitionCancel(Transition transition) {
    
            }
    
            @Override
            public void onTransitionPause(Transition transition) {
    
            }
    
            @Override
            public void onTransitionResume(Transition transition) {
    
            }
        });
    

    【讨论】:

    • 取决于你想要什么,这是错误的。如果您使用 SharedElementTransition 开始片段事务,那么您应该直接调用 getSharedElementEnterTransition() 而不从片段中调用 getActivity().getWindow() - 在 onAttach()
    • 嗨尼诺,感谢您的评论。这个片段不是事务的开始,而是结束。这是结束的好习惯吗?谢谢,
    • 是的,我在片段中就是这样做的。如果 fragmentA 调用 FragmentB 那么这将在 fragmentB 中。
    • 它也被要求退出。为什么?
    【解决方案4】:

    尝试在 Fragment A 而不是 B 上添加 TransitionListener。并使用android.support.transition.Transition

    片段 A

                val anim = DetailsTransition()
                anim.addListener(object : android.support.transition.Transition.TransitionListener
                {
                    override fun onTransitionEnd(transition: android.support.transition.Transition) {
                    }
    
                    override fun onTransitionResume(transition: android.support.transition.Transition) {
                    }
    
                    override fun onTransitionPause(transition: android.support.transition.Transition) {
                    }
    
                    override fun onTransitionCancel(transition: android.support.transition.Transition) {
                    }
    
                    override fun onTransitionStart(transition: android.support.transition.Transition) {
                    }
    
                })
    

    【讨论】:

      【解决方案5】:

      我在 Kotlin 中使用导航组件努力做到这一点,但设法让它与它一起工作

      override fun onCreateView(
          inflater: LayoutInflater, container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
          setAndPostponeEnterAnimation()
          _binding = PokemonDetailFragmentBinding.inflate(inflater, container, false)
          setInsets()
          handleNavigationArgs()
          return binding.root
      }
      
      private fun setAndPostponeEnterAnimation() {
          postponeEnterTransition()
          sharedElementEnterTransition = TransitionInflater.from(context)
              .inflateTransition(R.transition.shared_element_transition)
          addSharedElementListener()
      }
      
      private fun addSharedElementListener() {
          (sharedElementEnterTransition as TransitionSet).addListener((object :
              TransitionListenerAdapter() {
              override fun onTransitionEnd(transition: Transition) {
                  super.onTransitionEnd(transition)
                  createRevealAnimation()
              }
          }))
      }
      

      所以我可以在开始新动画之前等待共享过渡完成

      【讨论】:

      • 对我不起作用,甚至出现异常:无法转换为 TransitionSet
      • 导入的是andoirx.app,你的意思是我必须从android.app导入?
      • 除此之外,好像还有setEnterSharedElementCallback 用来处理onEnd 但是功能不太好
      • 不,我的意思是过渡集的导入可能不好
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      相关资源
      最近更新 更多