Android共享元素片段转换:返回转换不起作用

时间:2017-04-03 10:04:42

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

在我的项目中,我使用RecyclerView显示带缩略图的项目列表。当用户单击某个项目时,将打开DetailView,其中图像显示在顶部。我尝试在这些片段之间共享一些元素,但是过渡仅在输入细节片段时起作用,而不是在从它返回时起作用。

在我的ListAdapter我设置TransitionName并在用户点击某个项目时通知ListFragment:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        viewHolder.image.setTag(Constants.SHARED_NAME_IMAGE + item.itemId);
}

点击事件:

@OnClick(R.id.root)
 public void onClickedItem() {
        List<Pair<View, String>> sharedElements = new ArrayList<>();
        sharedElements.add(new Pair<View, String>(image, (String) image.getTag()));
        interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);
 }

然后在ListFragment中我开始使用DetailFragment:

public void navigateToFragment(Fragment curFragment, Fragment nextFragment,
                               boolean addToBackStack, List<Pair<View, String>> sharedElements) {
    if (nextFragment == null) {
        return;
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && sharedElements != null && curFragment != null) {
        // Setup transition on first fragment
        curFragment.setSharedElementEnterTransition(TransitionUtil.getReturnTransition(this));
        curFragment.setSharedElementReturnTransition(TransitionUtil.getEnterTransition(this));
        curFragment.setEnterTransition(null);
        curFragment.setExitTransition(null);

        // Setup transition on second fragment
        nextFragment.setSharedElementEnterTransition(TransitionUtil.getEnterTransition(this));
        nextFragment.setSharedElementReturnTransition(TransitionUtil.getReturnTransition(this));
        nextFragment.setEnterTransition(null);
        nextFragment.setExitTransition(null);

        // Add second fragment by replacing first
        FragmentTransaction ft = getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, nextFragment);
        if (addToBackStack) {
            ft.addToBackStack("fragment");
        }

        for (Pair<View, String> sharedElement : sharedElements) {
            ViewCompat.setTransitionName(sharedElement.first, sharedElement.second);
            ft.addSharedElement(sharedElement.first, sharedElement.second);
        }

        // Apply the transaction
        ft.commit();
    } else {
        FragmentTransaction ft = getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, nextFragment);
        if (addToBackStack) {
            ft.addToBackStack("fragment");
        }
        ft.commit();
    }
}

最后,我在DetailFragment的onCreateView()中设置当前转换名称(因为它取决于itemId):

ViewCompat.setTransitionName(header, Constants.SHARED_NAME_IMAGE + itemId);

1 个答案:

答案 0 :(得分:3)

我刚刚解决了这个问题:有两个问题:

  1. 我已经覆盖了我的列表适配器(因此删除了转换名称)
  2. 我没有在onBindViewHolder
  3. 中设置过渡名称

    要解决#1,我在这里改变了setUpList(){...}(第一个是重要的!):

     private void setupList() {
        if (adapter != null) {
            list.setAdapter(adapter);
            linearLayoutManager = new LinearLayoutManager(getActivity());
            list.setLayoutManager(linearLayoutManager);
            setScrollListener();
            return;
        }
    
        refreshLayout.setColorSchemeColors(ResourcesCompat.getColor(getResources(), R.color.main_color_2, getActivity().getTheme()));
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                loadList(true);
            }
        });
    
        adapter = new ListAdapter((int) (DisplayUtils.getWidth(getActivity()) * 0.6), this);
        list.setAdapter(adapter);
    
        linearLayoutManager = new LinearLayoutManager(getActivity());
        list.setLayoutManager(linearLayoutManager);
    
        refreshLayout.post(new Runnable() {
            @Override
            public void run() {
                refreshLayout.setRefreshing(true);
                loadFilterItems();
    

    要解决#2,我刚刚将setTag(..)替换为setTransitionName(..)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    vh.image.setTransitionName(Constants.SHARED_NAME_IMAGE + item.itemId);
                }
    

    并在我的onClick方法中:

     List<Pair<View, String>> sharedElements = new ArrayList<>();
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                sharedElements.add(new Pair<View, String>(image, image.getTransitionName()));
            }
     interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);