android – 嵌套共享元素的转换不是从预期的位置开始的

TL; DR为什么这种转变不是从预期的地方开始的?

也就是说,CardView的地方.

平台/代表:Android Studio 1.0-RC2,TargetSdk 21,MinSdk 21,AppCompat-21.0.2,CardView-21.0.2,RecyclerView-21.0.2.

测试:Genymotion Nexus 5棒棒糖预览

守则(简体)

我有三个共享元素:

资源:

<CardView
    android:transitionName="cardView">
    <ImageView
      android:transitionName="imageView">
    <TextView
      android:transitionName="textView">

目标:

<RelativeLayout
    android:transitionName="cardView">
    <ImageView
      android:transitionName="imageView">
    <TextView
      android:transitionName="textView">

请注意,转换名称是以编程方式添加的.这是因为CardView固定在RecyclerView上,并且有许多副本.我尝试使用相同的名称(如在XML实例中),但两者都不起作用.

ReciclerView.Adapter执行此操作:

@Override
public void onBindViewHolder(ViewHolder viewHolder,int position) {
    //...
    ViewCompat.setTransitionName(viewHolder.mCardView,"cardViewTransition" + position);
    ViewCompat.setTransitionName(viewHolder.mImageView,"imageTransition" + position);
    ViewCompat.setTransitionName(viewHolder.mTextView,"textTransition" + position);
    //...
}

HomeActivity这样做:

@Override
protected void onCreate(Bundle savedInstanceState) {
    getwindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);
    getwindow().requestFeature(android.view.Window.FEATURE_ACTIVITY_TRANSITIONS);
    // ..
    mRecyclerView.addOnItemTouchListener(
        new RecyclerItemClickListener(this,new RecyclerItemClickListener.OnItemClickListener() {
            @Override public void onItemClick(View view,int position) {
                Intent intent = new Intent(selfContext,DetailActivity.class);

                View imageView = view.findViewById(R.id.imageView);
                TextView textView = (TextView)view.findViewById(R.id.textView);

                Bundle extras = new Bundle();
                extras.putInt("position",position);
                extras.putString("text",textView.getText().toString());
                intent.putExtras(extras);
                String name = ViewCompat.getTransitionName(view);
                ActivityOptionsCompat options =
                    ActivityOptionsCompat.makeSceneTransitionAnimation(selfContext,Pair.create(view,ViewCompat.getTransitionName(view)),Pair.create(imageView,ViewCompat.getTransitionName(imageView)),Pair.create((View)textView,ViewCompat.getTransitionName(textView))
                    );
                ActivityCompat.startActivity(selfContext,intent,options.toBundle());
            }
        })
    );
    ///...
}

DetailActivity执行此操作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    getwindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);
    getwindow().requestFeature(android.view.Window.FEATURE_ACTIVITY_TRANSITIONS);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);

    // ...

    Bundle extras = getIntent().getExtras();
    int mPositionRef = extras.getInt("position");
    View base = findViewById(R.id.detail_layout);
    View image = findViewById(R.id.imageView);
    TextView text = (TextView) findViewById(R.id.txtLabel);
    text.setText(extras.getString("text"));

    ViewCompat.setTransitionName(base,"cardViewTransition" + mPositionRef);
    ViewCompat.setTransitionName(image,"imageTransition" + mPositionRef);
    ViewCompat.setTransitionName(text,"textTransition" + mPositionRef);

}

我已经调试过,共享元素在源和目标中具有相同的名称.

问题(再次)

为什么这种转变不是从预期的地方开始的?也就是说,CardView的地方.

GitHub完成样品

解决方法

Lollipop中存在一个与嵌套共享元素相关的已知错误(即同时将视图组及其子项之一添加为共享元素),因此它可能与此相关(源: Glitch when animating nested views in a shared element Activity transition?).

尝试仅将ImageView和TextView添加为共享元素(而不是父相对布局容器).

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...