12

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

 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();

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

任何帮助是极大的赞赏。

谢谢乔什

4

5 回答 5

8

带有 Android 导航组件的 KOTLIN

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

        postponeEnterTransition()
        view.doOnPreDraw { startPostponedEnterTransition() }

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

于 2020-02-24T16:54:00.260 回答
4

假设您有两个片段,A并且BA提交片段事务以启动片段B

那么这意味着 exit 和 reenter 转换应该设置为 on A, enter 和 return 转换应该设置为 on B

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

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

于 2015-03-13T18:37:45.333 回答
3

从切换

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

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

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

于 2015-12-26T21:09:47.963 回答
0

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;
        }
    });
}

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

于 2020-08-19T14:12:05.577 回答
0



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

有两个片段。一个有一个 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();
}

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

@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。

其他片段.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);
}

}


片段其他.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添加到您要转换的内容即可。

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

于 2016-04-26T06:48:41.533 回答