使用RecyclerView项目进行共享元素转换 - Android

时间:2016-03-12 20:58:29

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

我尝试使用回收器视图中的元素进行共享元素转换。当用户单击我的回收器视图项内的textview时,将打开详细信息活动。在详细内容活动中,我显示了一些信息,我还有一个标签布局,使用毕加索从网址加载一些图像。转换到详细活动是有效的,但如果用户在加载所有图像之前返回到主活动,则主活动中的回收器视图会在反向动画后消失!当我禁用共享元素转换时,问题就消失了。

这两项活动都与片段有关。所以,我试图在两个片段之间创建一个过渡,这两个片段处于不同的活动中。

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

在具有共享元素的详细活动的片段内(在onCreateView中):

profileImage.setTransitionName("profile"+position);

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

我已经陷入这个问题两天了,看不到发生了什么。如果您需要更多关于它的信息或代码,请询问。

谢谢!

1 个答案:

答案 0 :(得分:5)

问题是共享元素转换是由Activity生命周期中的早期框架启动的。转换必须捕获其目标视图的开始和结束状态,以便构建正常运行的动画。因此,如果框架在共享元素的最终大小,位置和大小在被调用的Activity中被给定之前启动共享元素转换,则转换将捕获其共享元素的不正确的结束值,并且生成的动画将完全失败。 />
如果共享元素依赖于异步加载的数据,AsyncTask,AsyncQueryHandler,Loader或类似的东西在最终出现在被调用活动中之前可以确定,那么框架可能会在该数据之前开始转换被送回主线程。
所以,解决方案如下:

  1. 在被叫活动的postponeEnterTransition()方法中致电onCreate()
  2. 如果您确定所有共享元素都已正确定位并调整大小,请致电startPostponedEnterTransition()以恢复转换。您会发现有用的常见模式是在OnPreDrawListener中启动推迟的转换,该转换将在共享元素进行测量和布局后调用。
  3. 你使用 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);