26

我正在开发的应用程序显示图像网格。当你点击一个图像时,它会进入细节视图。详细信息视图包含一个ViewPager,它允许您在网格中的每个图像之间滑动。这是通过传递路径列表(包含网格中的每个图像)以及点击图像的偏移量来完成的,因此可以将ViewPager设置为初始显示该页面。ViewPager碎片 - 共享元素转换

在ViewPager中的当前偏移页面的片段内部有一个共享元素转换的最佳方式是什么?网格(RecyclerView)图像应展开为当前页面中的全屏图像。我看到推迟和恢复活动转换的能力,因此应用程序将等待显示共享元素转换,直到从磁盘加载图像。但我希望能够使其在视图寻呼机中正确的页面生成动画,并且退出到用户返回时的当前页面(因为您可以在页面之间滑动)。如果你现在刷到不同的页面,最初的页面是什么动画回到网格。

当前,我为视图分页器的片段中的每个图像分配了格式为“image_ [index]”的transitionName。当我开始细节活动时,我使用相同的transitionName,索引是偏移量。

与此相关的是,我还想知道如何让长时间按压的涟漪效果。当您更改视图的激活状态时,它似乎取消了波纹。我想要一个类似于Gmail的效果,其中纹波重新开始并在长按完成后快速结束并触发激活状态。

+0

您可能想在另一篇文章中提出关于涟漪的第二个问题。另外,当我有更多时间时,我可以更深入地回答关于视图寻呼机和共享元素的问题,但现在您可以查看[此示例项目](https://github.com/alexjlockwood/activity -transitions)。几周前我写了它,听起来它几乎完全符合你所描述的内容。 :P – 2014-12-05 03:32:16

+0

@AlexLockwood好点。哇,你说得对,我只是跑了它,而这正是我所需要的;我将在接下来的几天看看它,谢谢! – afollestad 2014-12-05 04:35:36

+0

你好这不是为我工作..我想要的是,我有一个viewpager的片段中的列表,并点击任何项目我想处理图像到它的细节片段..我尝试了每个可能的解决方案,我到这里..但没有任何工作..任何帮助将不胜感激。提前感谢。 - – 2016-03-03 10:43:44

回答

34

从我可以告诉(和纠正我,如果我错了),你要实现的目标基本上是这样的:假设你有一个MainActivity,一个DetailsActivity和图像的任意一组。 MainActivity在网格中显示该组图像,而DetailsActivity在水平方向上显示同一组图像ViewPager。当用户选择MainActivity中的图像时,该图像应该从网格中的位置转换到第二个活动的ViewPager中的正确页面。

我们想要解决的问题是“如果用户在DetailsActivity内切换页面怎么办”?如果发生这种情况,我们希望更改将在返回转换期间使用的共享映像。默认情况下,活动转换框架将使用在输入转换期间使用的共享元素...但视图页面的页面已更改,所以显然我们想以某种方式覆盖此行为。要做到这一点,我们需要设置一个SharedElementCallbackMainActivityDetailsActivityonCreate()方法和覆盖onMapSharedElements()方法,像这样:

private final SharedElementCallback mCallback = new SharedElementCallback() { 
    @Override 
    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { 
     if (mCurrentImagePosition != mOriginalImagePosition) { 
      View sharedView = getImageAtPosition(mCurrentImagePosition); 
      names.clear(); 
      sharedElements.clear(); 
      names.add(sharedView.getTransitionName()); 
      sharedElements.put(sharedView.getTransitionName(), sharedView); 
     } 
    } 

    /** 
    * Returns the image of interest to be used as the entering/returning 
    * shared element during the activity transition. 
    */ 
    private View getImageAtPosition(int position) { 
     // ... 
    } 
}; 

为了更完整的解决方案,我创建了一个sample project on GitHub,将实现这一目标效果(在单个StackOverflow答案中发布的代码太多)。

+0

这是完美的,感谢您的帮助! – afollestad 2014-12-05 18:45:05

+0

你好,这不是为我工作..我想要的是,我有一个viewpager的片段中的列表,并点击任何项目,我想处理图像到它的细节片段..我尝试了我得到的每一个可能的解决方案..但没有任何工作..任何帮助将不胜感激。提前感谢。 - – 2016-03-03 10:43:49

+0

谢谢,非常有用! – schwertfisch 2016-04-19 16:44:07

3

我假设你正在使用片段转换,并且你没有在活动之间进行动画制作。它可以在活动转换和片段转换中使用,但具体的代码有点不同。尽管如此,延期在片段转换中不可用。

addSharedElement接受第二个参数。如果您在调用目标片段时知道目标片段中的特定名称,则可以选择要使用的详细片段中的名称。如果你不这样做,你可以选择你想要的任何名字,并使用Fragment上设置的SharedElementCallback重新映射它。

fragment.setEnterSharedElementCallback(new SharedElementCallback() { 
    @Override 
    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { 
     sharedElements.put("detailView", mTargetDetailView); 
    } 
}); 

如果它在回来的路上不匹配,则会进行相同的调用以重映射它。这可能会在调用片段和被调用片段中 - 在调用片段中,您使用setExitSharedElementCallback。我预计你的应用会出现这种情况。

同样,在Activity Transitions中,您设置了相同的SharedElementCallback并使用相同的映射,但是您在Activity上执行此操作。

+0

这绝对是我想要做的事情,问题是有两项活动。一个显示包含图像网格的碎片。另一个包含一个ViewPager,其中有详细的碎片。 – afollestad 2014-12-05 02:15:05

+0

您正在使用Activity转换,并且恰好您的视图处于碎片状态。您可能不得不推迟输入转换或在onCreate中执行挂起的片段事务。你现在看到什么问题? – 2014-12-06 05:17:13