【问题标题】:Reverse shared element transition on back背面的反向共享元素过渡
【发布时间】:2015-02-01 13:59:38
【问题描述】:

我目前正在使用以下代码将屏幕右侧的块转换为左侧的共享元素:

 FragmentDetail newFragment = FragmentDetail.newInstance(id);

 setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.trans_move));
 setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
 View block = view.findViewById(R.id.blocks);
 block.setTransitionName("block");

 newFragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.trans_move));
 newFragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));


 newFragment.setTransitionId(block.getTransitionName());
 FragmentTransaction trans = getFragmentManager().beginTransaction();
 trans.replace(R.id.container, newFragment);
 trans.addToBackStack(null);
 trans.addSharedElement(block, block.getTransitionName());
 trans.commit();

这完全符合我的要求,但我想在按下后退按钮时反转效果,将项目重新设置为动画。按原样播放爆炸动画,但不播放过渡。

非常感谢任何帮助。

谢谢 乔什

【问题讨论】:

  • 顺便说一句,您可以将TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode) 替换为new Explode()

标签: android transition shared-element-transition


【解决方案1】:

带有 Android 导航组件的 KOTLIN

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

        postponeEnterTransition()
        view.doOnPreDraw { startPostponedEnterTransition() }

如果您通过单击 RecyclerView 项目打开第二个片段,通常会使用此选项。

【讨论】:

  • 它对我有用,谢谢,伙计!刚刚投了你的两个答案。
【解决方案2】:

假设您有两个片段,ABA 提交片段事务以启动片段 B

这意味着退出和重新进入转换应该设置在A,进入和返回转换应该设置在B

您似乎在调用片段而不是被调用片段(在本例中为newFragment)上调用setSharedElementReturnTransition,这可能会导致问题。

顺便说一句,您应该考虑在片段的onCreate() 方法中调用set*****Transition()setSharedElement*****Transition() 方法,而不是在片段事务提交之前立即调用。如果片段被销毁并重新创建,这些转换将被遗忘......因此将它们设置在onCreate() 中会更安全。

【讨论】:

  • 感谢您的 BTW 建议!我想知道为什么片段被销毁和重新创建时没有发生转换。但我确实将setSharedElementEnterTransition() 放入了onActivityCreated(),因为TransitionInflater 需要一个活动或上下文,但仍然需要之前位置的setSharedElementEnterTransition()。你有没有办法把它放到onCreate()
【解决方案3】:

切换
trans.replace(R.id.container, newFragment);

trans.hide(oldFragment).add(R.id.container, newFragment).show(newFragment)

它应该可以工作(就像我的情况一样)。 恢复共享片段转换似乎只有在隐藏旧片段而不是替换它时才有效。

【讨论】:

    【解决方案4】:



    我遇到了同样的问题。购买我找到了解决方案。 你知道,这个问题有很多原因。我只是展示我的方式。 希望对你有帮助。

    有两个片段。 一个有一个 RecyclerView 小部件:

    ListFragment.java

    public class ListFragment extends Fragment implements RecyclerItemInter {
    
    @Bind(R.id.recycler_view)
    RecyclerView recyclerView;
    
    private OnListItemClickListener onListItemClickListener;
    
    public void setOnListItemClickListener(ListFragment.OnListItemClickListener onListItemClickListener) {
        this.onListItemClickListener = onListItemClickListener;
    }
    
    public ListFragment() {
    }
    
    public static ListFragment newInstance() {
        ListFragment fragment = new ListFragment();
        return fragment;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container, false);
        ButterKnife.bind(this, view);
        recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
        RecyclerAdapter2 adapter = new RecyclerAdapter2(BEAUTY_BEANS);
        recyclerView.setAdapter(adapter);
        adapter.setItemInter(this);
        return view;
    }
    
    private static final BeautyBean[] BEAUTY_BEANS = {
            new BeautyBean("Avril Lavigne1", "Avril was born in Canada, the Canadian singer, songwriter creators, actors."),
            new BeautyBean("Avril Lavigne2", "Avril was born in Canada, the Canadian singer, songwriter creators, actors."),
            new BeautyBean("Avril Lavigne3", "Avril was born in Canada, the Canadian singer, songwriter creators, actors."),
            new BeautyBean("Avril Lavigne4", "Avril was born in Canada, the Canadian singer, songwriter creators, actors."),
            new BeautyBean("Avril Lavigne5", "Avril was born in Canada, the Canadian singer, songwriter creators, actors.")
    };
    
    
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }
    
    @Override
    public void onItemClick(View view, int position) {
    }
    
    @Override
    public void onIvClick(RecyclerAdapter2.ViewHolder holder, int position) {
        OtherFragment otherFragment = OtherFragment.newInstance();
        otherFragment.setSharedElementEnterTransition(new CustomTransition());
        otherFragment.setSharedElementReturnTransition(new CustomTransition());
    
        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            otherFragment.setEnterTransition(new Fade());
            setExitTransition(new Fade());
        }*/
    
        getActivity().getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.frame_layout, otherFragment)
                .addToBackStack(null)
                .addSharedElement(holder.getPicIv(), getString(R.string.transition_img))
                .commit();
    }
    

    那么你应该为 RecyclerView 中的每个 ImageView 设置 TransitionName:

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        if (items[position].getImageId() != 0) {
            holder.getPicIv().setImageResource(items[position].getImageId());
        }
        ViewCompat.setTransitionName(holder.getPicIv(), String.valueOf(position) + "_beauty");
    
        holder.getTitleTv().setText(items[position].getName());
        holder.getDescTv().setText(items[position].getDesc());
        holder.getLinearLayout().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != itemInter) {
                    itemInter.onItemClick(holder.itemView, position);
                }
            }
        });
        holder.getPicIv().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != itemInter) {
                    itemInter.onIvClick(holder, position);
                }
            }
        });
    }
    

    点击列表跳转到OtherFragment。

    OtherFragment.java

    public class OtherFragment extends Fragment {
    
    public OtherFragment() {
    }
    
    public static OtherFragment newInstance() {
        OtherFragment fragment = new OtherFragment();
        return fragment;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_other, container, false);
    }
    

    }


    fragment_other.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jacksen.supportlibrarydemo.fragment.OtherFragment">
    
    
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/bg_detail_header"
        android:transitionName="@string/transition_img" />
    
    
    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_backup_white_36dp"
        android:transitionName="@string/transition_fab"
        app:borderWidth="0dp"
        app:elevation="5dp"
        app:pressedTranslationZ="10dp"
        app:rippleColor="@color/color_gray" />
    


    问题的症结在于这个xml。 一开始,我设置了属性“transitionName”及其父布局。 其实我们不需要在父Layout上添加属性。

    只需将 transitionName 添加到您要转换的内容中。

    好的,这就是我的解决方案。

    【讨论】:

      【解决方案5】:

      Joe Muller 的答案是正确的,我是为 Java 编写的

      @Override
      public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
          super.onViewCreated(view, savedInstanceState);
          postponeEnterTransition();
          view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
              @Override
              public boolean onPreDraw() {
                  startPostponedEnterTransition();
                  view.getViewTreeObserver().removeOnPreDrawListener(this);
                  return false;
              }
          });
      }
      

      如果开始转换在适配器内部,这将解决问题

      【讨论】:

        猜你喜欢
        • 2016-04-23
        • 2016-02-04
        • 1970-01-01
        • 2018-07-14
        • 2019-08-07
        • 2018-03-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-29
        相关资源
        最近更新 更多