【问题标题】:Shared Element Transition with RecyclerView items - Android使用 RecyclerView 项目的共享元素转换 - Android
【发布时间】:2016-03-12 20:58:28
【问题描述】:

我正在尝试使共享元素转换与回收器视图中的元素一起工作。当用户单击我的回收站视图项中的文本视图时,将打开详细信息活动。在 Detail Activity 中,我显示了一些信息,并且还有一个选项卡布局,可以使用 picasso 从 url 加载一些图像。到 Detail Activity 的转换正在工作,但是如果用户在加载所有图像之前返回到 Main Activity,则在反向动画之后,Main Activity 中的回收器视图会消失!当我禁用共享元素转换时,问题就消失了。

这两个活动都使用片段。所以,我正在尝试在不同活动中的两个片段之间创建一个过渡。

在 RecyclerViewAdapter 中,我设置了过渡名称:

public void onBindViewHolder(final ViewHolder viewHolder, int position) {
  ... 
 viewHolder.profileImage.setTransitionName("profile"+position);

我的 textview 的 onClickListener(在 Main Activity 的片段内):

Intent i = new Intent(getCurrentActivity(), DetailActivity.class);
        ActivityOptionsCompat options = ActivityOptionsCompat.
               makeSceneTransitionAnimation(getCurrentActivity(), (View) profileImage, "profile"+position);
        getCurrentActivity().startActivity(i, options.toBundle());

在具有共享元素的 Detail Activity 片段内(在 onCreateView 中):

profileImage.setTransitionName("profile"+position);

当意图发生时,我已经检查了两个活动中的转换名称,并且它是相同的。

我被这个问题困扰了两天,看不到发生了什么。如果您需要有关它的更多信息或代码,请询问。

谢谢!

【问题讨论】:

  • 我不知道这是否重要,但两个活动(主要和细节)都有片段,因此从主要活动的片段和第二个活动的 setTransitionName() 调用详细活动的意图在其片段的 onCreateView() 内部调用。
  • 当然你会遇到这个问题。 Picasso 是后台的异步调用,如果它的任务未完成,那么您将移至另一个 Activity,即您的 MainActivity。来自毕加索的异步调用将被停止。 @G_comp。我认为他没有使用 Fragments,因为您在 FragmentTransactions 上设置了 Transition。
  • @Aizen 但问题只发生在启用共享元素转换时,所以我认为这不是毕加索的错。当我禁用共享元素转换时,我可以在加载图像之前返回主活动而不会出现问题
  • 这不是毕加索的错,只是毕加索也会停止它的召唤。主要问题是过渡。您故意停止 MainActivity 进程并转到 Detail,所以当您返回 Main 时。它是不完整的。您需要使用正确的片段处理。不让 MainActivity 关闭它的进程以及当有人点击它时。您只需要获取片段事务并添加详细信息活动,这样您就可以避免暂停主要活动。 Intent i = new Intent(getCurrentActivity(), DetailActivity.class) 没有创建 Fragments。
  • 当你创建一个 Intent 时,正在创建这个 Intent 的 Activity 仍在运行。但是,当您调用 startActivity。那就是您当前的活动将被暂停并被另一个活动取代的时候。在 Fragment 中,它们都将同时运行,因为它们是 FragmentManager 持有的 Activity 的一部分。我希望你明白我的意思。

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


【解决方案1】:

问题在于共享元素转换是由框架在 Activity 生命周期的早期启动的。转换必须捕获其目标视图的开始和结束状态,才能构建正常运行的动画。因此,如果框架在其共享元素在被调用的 Activity 中被赋予其最终大小、位置和大小之前开始共享元素转换,则转换将为其共享元素捕获不正确的结束值,并且生成的动画将完全失败。

如果 共享元素依赖于由 AsyncTask、AsyncQueryHandler、Loader 或类似的东西异步加载的数据,然后才能确定它们在被调用活动中的最终外观,则框架可能会在该数据之前开始转换被传递回主线程。
因此,解决方案如下:

  1. 在您调用的活动的onCreate()方法中调用postponeEnterTransition()
  2. 当您确定所有共享元素都已正确定位和调整大小时,请致电startPostponedEnterTransition() 以恢复过渡。您会发现一个有用的常见模式是在 OnPreDrawListener 中启动延迟转换,它将在共享元素被测量和布局后调用。

您使用 Picasso ,因为我知道 Picasso 在加载图像时有一个名为 RequestCreator 的回调。
例如:

private final Callback callBack = new Callback() {
    @Override
    public void onSuccess() {
        imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                imageView.getViewTreeObserver().removeOnPreDrawListener(this);
                MainActivity.this.startPostponedEnterTransition();
                return true;
            }
        });
    }

    @Override
    public void onError() {

    }
};

RequestCreator requestCreator = Picasso.with(this).load(imageUrl);
requestCreator.into(imageView, callback);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多