TL;DR:为什么这个转换没有从预期的位置开始?也就是 CardView 所在的位置。
平台/依赖:Android Studio 1.0-RC2,目标 SDK 21,最小 SDK 21,AppCompat-21.0.2,CardView-21.0.2,RecyclerView-21.0.2。
测试环境:Genymotion Nexus 5 Lollipop 预览版
代码(简化版)
我有三个共享元素:
源码:
<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);
}
我已经调试过了,分享的元素在源和目标中具有相同的名称。
问题(再次提出)
为什么这个转换不是从预期的位置开始的呢?也就是说,卡片视图所在的位置。
完整的示例在GitHub上。
ImageView
和TextView
作为共享元素添加(而不是父相对布局容器)。 - Alex Lockwood