我正在尝试在Master Detail情况下从ListView执行Android 5.0共享元素转换,发送的是一张图片。
我在进入转换中遇到了一个故障,在Master活动转换出时,图像根本不动。一旦加载了Detail活动,图像就会从屏幕左上角开始动画,并动画到其最终位置。返回转换运作完美 - 图像从它的Detail位置到Master中适当的位置进行动画。
这是它的样子:https://www.youtube.com/watch?v=AzyA8i27qWc 我相信我已经正确设置了权限并指定了转换。
我已经为列表中的两个视图分别赋予了相同的unique transitionName属性,基于它们在列表中的位置。
我正在使用makeSceneTransitionAnimation来进行动画:
解决方法是将该行替换为:
我猜调用适配器的getView方法会重新创建视图本身 - 我猜这个方法应该只在列表第一次创建时调用。
我在进入转换中遇到了一个故障,在Master活动转换出时,图像根本不动。一旦加载了Detail活动,图像就会从屏幕左上角开始动画,并动画到其最终位置。返回转换运作完美 - 图像从它的Detail位置到Master中适当的位置进行动画。
这是它的样子:https://www.youtube.com/watch?v=AzyA8i27qWc 我相信我已经正确设置了权限并指定了转换。
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform</item>
这个过渡效果的定义如下:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeImageTransform/>
<changeBounds/>
<changeTransform/>
</transitionSet>
我已经为列表中的两个视图分别赋予了相同的unique transitionName属性,基于它们在列表中的位置。
我正在使用makeSceneTransitionAnimation来进行动画:
View photo = (View) adapter.getView(position, null, listView).findViewById(R.id.photo);
View navigationBar = findViewById(android.R.id.navigationBarBackground);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(photo, photo.getTransitionName()),
Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
Bundle extras = new Bundle();
Patient selectedPatient = patientList.get(position);
extras.putParcelable("patient", selectedPatient);
extras.putInt("position", position);
Intent intent = new Intent(PatientListActivity.this, PatientActivity_.class);
intent.putExtras(extras);
startActivity(intent, options.toBundle());
我还将navigationBar指定为共享,以避免其淡出,这个方法运行良好。
我不明白为什么返回过渡效果正常,但进入过渡效果不正常。我看到其他问题的解决方案是延迟进入过渡效果,我已经尝试了这样做,但问题仍然存在。以下是我在详情活动中onCreate中添加的内容:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient);
patient = getIntent().getExtras().getParcelable("patient");
patient = app.getPatientByName(patient.getName());
patientPhotoView.setImageDrawable(patient.getPhoto());
/* Set up transition functionality */
position = getIntent().getExtras().getInt("position");
patientPhotoView.setTransitionName("patientPhoto" + position);
patientNameView.setTransitionName("patientName" + position);
postponeEnterTransition();
final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
observer.removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
在我的详细活动中,没有 transitionName 元素,但我正在代码中进行设置。传入活动(详细信息)的相关部分如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PatientActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dip"
android:orientation="vertical"
android:id="@+id/patient_top_layout">
<ImageView
android:id="@+id/patientPhoto"
android:layout_width="92dip"
android:layout_height="92dip"
android:layout_below="@+id/connectionBar"
android:layout_marginRight="12dip"
android:layout_marginTop="12dip"
android:contentDescription="Patient photo"
android:src="@drawable/ic_profile_default" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout
很高兴发布其他相关的代码。有什么想法吗?
已解决
Android开发Google+页面上的用户Chris P替我解决了这个问题。在我的主Activity中的onClick方法中,我写了:
View photo = (View) adapter.getView(position, null, listView).findViewById(R.id.photo);
解决方法是将该行替换为:
View photo = (View) listView.getChildAt(position).findViewById(R.id.photo);
我猜调用适配器的getView方法会重新创建视图本身 - 我猜这个方法应该只在列表第一次创建时调用。
@transition/change_image_transform
改成@transition/change_image_transform
,会有什么不同吗?如果你将getWindow().getDecorView()
改成你正在使用的共享元素ImageView
对象,会有什么不同吗? - Alex LockwoodgetWindow().getDecorView()
更改为patientPhotoView
(在设置转换名称和照片后)时,没有任何区别。 - clay_to_n@transition/change_image_transform
更改为@android:transition/move
,会有什么区别吗? - Alex Lockwood