片段共享单元的转换不与ViewPager工作 [英] Fragment shared element transitions don't work with ViewPager

查看:363
本文介绍了片段共享单元的转换不与ViewPager工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序包含了由碎片组成的少数的ViewPager的景色。当您在这些片段中的一个点击的项目,预期的行为是共享的元素(在这种情况下的图像)过渡到显示有关点击的内容的更多信息片段。

My app contains a view which consists of a ViewPager consisting of a handful of fragments. When you click on an item in one of these fragments, the expected behavior is for the shared element (in this case an image) to transition to the fragment which displays more information about the clicked content.

下面是一个非常简单的它应该是什么样子的视频:

Here is a very simple video of what it should look like:

<一个href=\"https://dl.dropboxusercontent.com/u/97787025/device-2015-06-03-114842.mp4\">https://dl.dropboxusercontent.com/u/97787025/device-2015-06-03-114842.mp4

这是只使用一个Fragment->片段过渡。

This is just using a Fragment->Fragment transition.

在出现问题时,你把一个ViewPager内的起始片段。我怀疑这是因为ViewPager使用其父段的孩子​​片段经理,比活动的片段经理,正在处理的片段交易不同。这里是发生了什么视频:

The problem arises when you place the starting fragment inside a ViewPager. I suspect this is because the ViewPager uses its parent fragment's child fragment manager, which is different than the fragment manager of the activity, which is handling the fragment transaction. Here is a video of what happens:

<一个href=\"https://dl.dropboxusercontent.com/u/97787025/device-2015-06-03-120029.mp4\">https://dl.dropboxusercontent.com/u/97787025/device-2015-06-03-120029.mp4

我是pretty一定这里的问题,我上面的解释是孩子片段经理VS活动的片段经理。这里是我想提出的过渡:

I'm pretty certain the issue here as I explained above is the child fragment manager vs the activity's fragment manager. Here is how I am making the transition:

SimpleFragment fragment = new SimpleFragment();

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.am_list_pane, fragment, fragment.getClass().getSimpleName());

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    TransitionSet enterTransition = new TransitionSet();
    enterTransition.addTransition(new ChangeBounds());
    enterTransition.addTransition(new ChangeClipBounds());
    enterTransition.addTransition(new ChangeImageTransform());
    enterTransition.addTransition(new ChangeTransform());

    TransitionSet returnTransition = new TransitionSet();
    returnTransition.addTransition(new ChangeBounds());
    returnTransition.addTransition(new ChangeClipBounds());
    returnTransition.addTransition(new ChangeImageTransform());
    returnTransition.addTransition(new ChangeTransform());

    fragment.setSharedElementEnterTransition(enterTransition);
    fragment.setSharedElementReturnTransition(returnTransition);

    transaction.addSharedElement(iv, iv.getTransitionName());
}

transaction.addToBackStack(fragment.getClass().getName());

transaction.commit();

当两个片段是由活动的片段经理管理这工作得很好,但是当我加载了一个ViewPager是这样的:

This works fine when both fragments are managed by the activity's fragment manager, but when I load up a ViewPager like this:

ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(new Adapter(getChildFragmentManager()));

在ViewPager的儿童没有被活动管理的,它不工作了。

The children of the ViewPager are not being managed by the activity, and it doesn't work anymore.

这是由Android团队的疏忽?有什么办法拉这一关?谢谢你。

Is this an oversight by the Android team? Is there any way to pull this off? Thanks.

推荐答案

也许你已经找到了答案,这但如果你没有,这是我做了几个小时后修复它抓我的头

Probably you've already found an answer to this but in case you haven't, here's what I did to fix it after a few hours of scratching my head.

我觉得这个问题是两个因素的结合:

The problem I think is a combination of two factors:


  • Fragmnets ViewPager 的延迟加载,这意味着该活动恢复了不少速度比这是包含在 ViewPager

  • The Fragmnets in ViewPager load with a delay, meaning that the activity returns a lot faster than its fragments which are contained inside the ViewPager

如果你像我一样,你的 ViewPager 的孩子碎片很可能是同一类型。这意味着,他们都有着相同的过渡名称(如果你设置他们在您的XML布局),,除非你把其中的code和只设置一次,在可见的片段

If you are like me, your ViewPager's child fragments are most likely the same type. This means, they all share the same transition name (if you've set them in your xml layout), unless you set them in code and only set it once, on the visible fragment.

要解决这两个问题,这就是我所做的:

To fix both of these problems, this is what I did:

1。固定延迟加载问题:

在你的活动(包含一个 ViewPager ),在 super.onCreate()加入这一行之前的setContentView()

Inside your activity (the one that contains the ViewPager), add this line after super.onCreate() and before setContentView():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActivityCompat.postponeEnterTransition(this); // This is the line you need to add

    setContentView(R.layout.feeds_content_list_activity);
    ...
}

2。固定用相同的过渡名称的多个片段的问题:

现在也有去这样做呢不少办法,但是这是我结束了我的细节的活动里面,即包含 ViewPager 活动(在的onCreate(),但你可以在任何地方真的):

Now there are quite a few ways of going about doing this but this is what I ended up with inside my "detail" activity, i.e. the activity that contains the ViewPager (in the onCreate() but you can do it anywhere really):

_viewPager.setAdapter(_sectionsPagerAdapter);
_viewPager.setCurrentItem(position);
...
...
_pagerAdapter.getItem(position).setTransitionName(getResources().getString(R.string.transition_contenet_topic));

您需要小心,因为活动可能尚未所以它更容易连接到你的 ViewPager 片段只是在过渡名称传递从活动的片段,如果你从资源加载它

You need to be careful since the Activity may not yet be attached to your ViewPager fragment so it's easier to just pass in the transition name from the activity to the fragment if you're loading it from a resource

如您所愿实际的实现很简单:

The actual implementation is as simple as you expect:

public void setTransitionName(String transitionName) {
    _transitionName = transitionName;
}

然后里面的片段的 onViewCreated(),加入这一行:

public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ...
    if (_transitionName != null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        setTransitionNameLollipop();
    }
    ...
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setTransitionNamesLollipop() {
    _imgTopic.setTransitionName(_transitionName);
}

拼图的最后一块是找出当你的片断完全加载,然后调用 ActivityCompat.startPostponedEnterTransition(getActivity());

在我的情况,我的片段,没有完全加载,直到后来因为我加载大部分东西了UI线程,这意味着我必须想出一个办法,当一切都被加载到调用此,但如果这不是你的情况,你你打电话后可以调用这个正确的 setTransitionNameLollipop()

In my case, my fragments were not fully loaded until later since I'm loading most things off the UI thread which means I had to figure out a way to call this when everything was loaded but if that's not your case, you can call this right after you call setTransitionNameLollipop().

这种方法的问题是,出口过渡可能不工作,除非你非常小心,权利之前对看得见的片段重新转换名称您退出活性导航回。这可以很容易地像这样来完成:

The problem with this approach is that the exit transition may not work unless you're very careful and reset the transition name on the "visible" fragment right before you exit the activity to navigate back. That can easily be done like so:


  1. 听在页面修改你的 ViewPager

  2. 删除过渡姓名(或名称),只要你的片段是拿出来看

  3. 在可视片段设置过渡姓名(或名称)。

  4. 而不是调用的完成(),电话 ActivityCompat.finishAfterTransition(活动);

  1. Listen to page change on your ViewPager
  2. Remove the transition name(s) as soon as your fragment is out of view
  3. Set the transition name(s) on the visible fragment.
  4. Instead of calling finish(), call ActivityCompat.finishAfterTransition(activity);

这可能会非常复杂的很快,如果你回转型需要过渡到 RecyclerView 这是我的情况。为此,有通过@Alex洛克伍德这里提供一个更好的答案:<一href=\"http://stackoverflow.com/questions/27304834/viewpager-fragments-shared-element-transitions\">ViewPager片段 - 共享元素转换其中有一个写得很好的例子code(虽然有很多比我刚写更复杂的)位置:<一href=\"https://github.com/alexjlockwood/activity-transitions/tree/master/app/src/main/java/com/alexjlockwood/activity/transitions\">https://github.com/alexjlockwood/activity-transitions/tree/master/app/src/main/java/com/alexjlockwood/activity/transitions

This can get very complex very soon if you back transition needs to transition to a RecyclerView which was my case. For that, there's a much better answer provided by @Alex Lockwood here: ViewPager Fragments – Shared Element Transitions which has a very well written example code (albeit a lot more complicated than what I just wrote) here: https://github.com/alexjlockwood/activity-transitions/tree/master/app/src/main/java/com/alexjlockwood/activity/transitions

在我的情况,我没有走这么远,实施他的解决办法,我贴我的情况制定上述方案。

In my case, I didn't have to go so far as to implement his solution and the above solution that I posted worked for my case.

如果你有多个共享的元素,我相信你能弄清楚如何扩展,以迎合他们的方法。

In case you have multiple shared elements, I'm sure you can figure out how to extend the methods in order to cater to them.

这篇关于片段共享单元的转换不与ViewPager工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆