Android - 具有多个共享元素的不同过渡
Android - Different transitions with multiple shared elements
我正在使用 Android Lollipop Transitions,我偶然发现了以下问题:
- 我有
CardView
和一个 ImageView
,在它上面还有一个 TextView
。
- 当我点击卡片时,会启动一个新的 Activity,它包含不同位置的
ImageView
和 TextView
。
- 如果我不将
TextView
作为共享元素包含在 Transition
中,它会突然消失 [落后于] ImageView
,这看起来并不好,太好了。
- 如果我包含它,它不会很好地缩放文本并突然更改为最终大小(我已经知道 this solution,但问题是我还想保留默认值
ImageView
Transition
,它是 ChangeBounds
Transition
、ChangeImageTransform
、...等等的组合。
所以,有人知道在启动新的 Activity
时如何为不同的共享视图抛出不同的转换吗?
干杯
好的,
这可以通过扩展过渡 class 来实现。因为我想为 ImageView 和 TextView 设置不同的动画,所以我只写了 Transform
的 TextTransform
子 class,类似于 ChangeImageTransform
的 ChangeImageTransform
是 Android API 21+。关键是覆盖此方法(显示寻找 ImageView
个对象的 ChangeImageTransform 的情况):
@Override
private void captureValues(TransitionValues transitionValues) {
View view = transitionValues.view;
if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
return;
}
(...)
}
然后将所有变换应用到新场景,相关变换将附加到它们对应的视图:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<fade android:fadingMode="fade_out" />
<changeBounds />
<changeImageTransform />
<com.mypackage.transforms.TextTransform />
<fade android:fadingMode="fade_in" />
</transitionSet>
然后您使用 setSharedElementEnterTransition(inflatedTransitionSet);
在新 Activity
的 OnCreate 方法上设置此 Transition
您在回答中指出的方式可用于此目的,但实际上它仅接受特殊 transition
的合适 View
类型(例如仅 ImageView
ChangeImageTransform
).
您可以使用addTarget(Class targetType)
代替:
final Transition transition = new TransitionSet()
.addTransition(new ChangeTransform()).addTarget(TextView.class) // Only for TextViews
.addTransition(new ChangeImageTransform()).addTarget(ImageView.class) // Only for ImageViews
.addTransition(new ChangeBounds()); // For both
setSharedElementEnterTransition(transition);
这种方式更简单,更符合逻辑。此外,它还可以用于其他一些过滤(通过 transitionName
等)。请参阅 addTarget()
重载类型。
我正在使用 Android Lollipop Transitions,我偶然发现了以下问题:
- 我有
CardView
和一个ImageView
,在它上面还有一个TextView
。 - 当我点击卡片时,会启动一个新的 Activity,它包含不同位置的
ImageView
和TextView
。 - 如果我不将
TextView
作为共享元素包含在Transition
中,它会突然消失 [落后于]ImageView
,这看起来并不好,太好了。 - 如果我包含它,它不会很好地缩放文本并突然更改为最终大小(我已经知道 this solution,但问题是我还想保留默认值
ImageView
Transition
,它是ChangeBounds
Transition
、ChangeImageTransform
、...等等的组合。
所以,有人知道在启动新的 Activity
时如何为不同的共享视图抛出不同的转换吗?
干杯
好的,
这可以通过扩展过渡 class 来实现。因为我想为 ImageView 和 TextView 设置不同的动画,所以我只写了 Transform
的 TextTransform
子 class,类似于 ChangeImageTransform
的 ChangeImageTransform
是 Android API 21+。关键是覆盖此方法(显示寻找 ImageView
个对象的 ChangeImageTransform 的情况):
@Override
private void captureValues(TransitionValues transitionValues) {
View view = transitionValues.view;
if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
return;
}
(...)
}
然后将所有变换应用到新场景,相关变换将附加到它们对应的视图:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<fade android:fadingMode="fade_out" />
<changeBounds />
<changeImageTransform />
<com.mypackage.transforms.TextTransform />
<fade android:fadingMode="fade_in" />
</transitionSet>
然后您使用 setSharedElementEnterTransition(inflatedTransitionSet);
Activity
的 OnCreate 方法上设置此 Transition
您在回答中指出的方式可用于此目的,但实际上它仅接受特殊 transition
的合适 View
类型(例如仅 ImageView
ChangeImageTransform
).
您可以使用addTarget(Class targetType)
代替:
final Transition transition = new TransitionSet()
.addTransition(new ChangeTransform()).addTarget(TextView.class) // Only for TextViews
.addTransition(new ChangeImageTransform()).addTarget(ImageView.class) // Only for ImageViews
.addTransition(new ChangeBounds()); // For both
setSharedElementEnterTransition(transition);
这种方式更简单,更符合逻辑。此外,它还可以用于其他一些过滤(通过 transitionName
等)。请参阅 addTarget()
重载类型。