【问题标题】:Android: Shared Element - return transition not workingAndroid:共享元素 - 返回过渡不起作用
【发布时间】:2020-02-25 01:10:43
【问题描述】:

我实现了从 recyclerview 到片段之间的共享元素转换。 enter 过渡效果很好,但我不知道为什么 return 过渡不起作用。

来自第一个片段的 RecyclerView 适配器

public void onBindViewHolder(@NonNull final MenuItemViewHolder holder, int position)
{
  holder.setData(category, data.get(holder.getAdapterPosition()));
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
  {
    MenuItem item = data.get(holder.getAdapterPosition());
    ViewCompat.setTransitionName(holder.name, item.getName());
    ViewCompat.setTransitionName(holder.image, item.getImage());
    ViewCompat.setTransitionName(holder.price, item.getId());
  }

  holder.setViewClick(new View.OnClickListener()
  {
    @Override
    public void onClick(View v)
    {
      try
      {
        if (context != null)
        {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
          {
            showFragment(category, data.get(holder.getAdapterPosition()), holder.name, holder.price, holder.image, holder.isLoaded());
          }
          else
          {
            Gson gson = new Gson();
            Bundle bundle = new Bundle();
            bundle.putString(Values.CAT_DATA, gson.toJson(category));
            bundle.putString(Values.ITM_DATA, gson.toJson(data.get(holder.getAdapterPosition())));
            ((MainActivity) context).showFragment(ProductViewFragment.class, null, bundle);
          }
        }
      }
      catch (NullPointerException | ClassCastException e)
      {
        e.printStackTrace();
      }
    }
  });
}

showFragment();

我尝试在每个片段中添加退出和进入过渡,但它仍然不起作用,因此我将其设置为 null,认为动画存在冲突但问题仍然存在。

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void showFragment(MenuCategory category, MenuItem menuItem, TextView name, TextView price,
  ImageView image, boolean isLoaded)
{
  try
  {
    if (context != null)
    {
      if (fragment != null)
      {
        //current fragment
        this.fragment.setSharedElementReturnTransition(
          TransitionInflater.from(context).inflateTransition(android.R.transition.move));
        this.fragment.setExitTransition(null);
      }

      ProductViewFragment fragment = ProductViewFragment.newInstance(category, menuItem, isLoaded);
      //next fragment
      fragment.setEnterTransition(null);
      fragment.setSharedElementEnterTransition(
        TransitionInflater.from(context).inflateTransition(android.R.transition.move));

      FragmentManager manager = ((MainActivity) context).getSupportFragmentManager();
      if (manager != null)
      {
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.setReorderingAllowed(true);
        transaction.addSharedElement(name, ViewCompat.getTransitionName(name));
        transaction.addSharedElement(price, ViewCompat.getTransitionName(price));
        transaction.addSharedElement(image, ViewCompat.getTransitionName(image));
        transaction.replace(R.id.container, fragment);
        transaction.addToBackStack(null);
        transaction.commit();
      }
    }
  }
  catch (NullPointerException | ClassCastException e)
  {
    e.printStackTrace();
  }
}

ProductViewFragment

我在设置视图时有这个

ViewCompat.setTransitionName(name, menuItem.getName());
ViewCompat.setTransitionName(image, menuItem.getImage());
ViewCompat.setTransitionName(price, menuItem.getId());

并在我将图像加载到视图中后调用supportStartPostponedEnterTransition()

@Override
public void onLoadingComplete(String imageUri, final View view, Bitmap loadedImage)
{
  view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
  {
    @Override
    public boolean onPreDraw()
    {
      if (getActivity() != null)
      {
        view.getViewTreeObserver().removeOnPreDrawListener(this);
        getActivity().supportStartPostponedEnterTransition();
      }
      return true;
    }
  });
}

我似乎不知道问题出在哪里,非常感谢任何帮助!

【问题讨论】:

    标签: android android-animation shared-element-transition


    【解决方案1】:

    带有 Android 导航组件的 KOTLIN

    对于在使用 Android Navigation 组件时在这里寻找此问题答案的任何人,您可以通过将以下几行添加到起始片段的 onViewCreated 函数来使反向过渡动画工作:

            postponeEnterTransition()
            view.doOnPreDraw { startPostponedEnterTransition() }
    

    如果您通过单击 RecyclerView 项目打开第二个片段,通常会使用postponeEnterTransition/startPostponedEnterTransition

    【讨论】:

    • 太棒了!我一直在寻找这个解决方案!
    • 如果您使用 Java,将 postponeEnterTransition(); OneShotPreDrawListener.add(view, this::startPostponedEnterTransition); 添加到 onViewCreated 对我有用。
    • 这就像一个魅力。谢谢
    【解决方案2】:

    我设法通过删除transaction.setReorderingAllowed(true);来解决它。

    【讨论】:

    • 我相信如果你删除setReorderingAllowed,你可能会得到一些意想不到的结果,而且当你有 SharedElementTransitions 时,你不必显式指定返回转换,它是自动的,一旦你指定了输入转换return one 与之相反,并且是自动设置的。此外,当您使用 ViewCompat 设置转换名称时,您无需检查我相信的版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    • 2018-07-14
    相关资源
    最近更新 更多