不同活动的片段之间的共享元素转换
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不同活动的片段之间的共享元素转换相关的知识,希望对你有一定的参考价值。
我正在尝试在不同活动的片段之间实现共享元素转换,我已经获得了共享元素进入转换但无法管理返回转换。
片段A托管在活动A中,按钮单击,图像作为共享元素添加,活动B在托管片段B的情况下启动,其中包含共享元素的目标视图。
活动A:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.content, FragmentA.newInstance())
.commit();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
片段A:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
setSharedElementReturnTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final ImageView imageView = (ImageView) view.findViewById(R.id.simple_activity_a_imageView);
Button button = (Button) view.findViewById(R.id.simple_activity_a_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ActivityB.class);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
imageView,
ViewCompat.getTransitionName(imageView));
startActivity(intent, options.toBundle());
}
});
}
活动B:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_to_fragment);
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.content, FragmentB.newInstance())
.commit();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
片段B:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
setSharedElementReturnTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView detailTextView = (TextView) view.findViewById(R.id.simple_activity_b_text);
detailTextView.setText("detail");
ImageView imageView = (ImageView) view.findViewById(R.id.simple_activity_b_image);
imageView.setVisibility(View.VISIBLE);
view.findViewById(R.id.activity_simple_two).setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
imageView.setTransitionName(getString(R.string.simple_activity_transition));
}
Glide.with(this)
.load(GlideFragmentA.ARMADILLO_PIC_URL)
.centerCrop()
.dontAnimate()
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
startPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
startPostponedEnterTransition();
return false;
}
})
.into(imageView);
}
非常简化,Fragments基本上是花哨的ViewGroups,它们有自己的生命周期和逻辑,它们是Activity的视图树的一部分,就像任何其他ViewGroup一样。因此,在查看两个活动之间的转换时,您实际上并未执行片段级共享元素转换,而是在活动级别上执行转换。
有必要确保在目标活动中,如果目标视图(共享元素)是添加在顶部的片段的一部分,则当转换框架开始捕获转换的结束值时,此目标视图已准备就绪,以便它可以在视图层次结构中找到。
FragmentManager的commit()不会立即执行事务和布局更改,但会很快将它们安排在一个点上,在您的情况下会导致上述情况不是这样。将目标活动中的输入转换推迟到片段的视图准备就绪(例如,首先调用其根布局的onPreDraw())应该修复该部分。这意味着,您必须在活动参考上调用活动B中的postponeEnterTransition()而不是片段B,并调用startPostponedEnterTransition()(Glide加载侦听器的一部分),而不是片段B本身。
此外,您需要在活动B上设置共享元素转换(输入和返回),因为它是实际运行它们的组件。设置这些先决条件后,您所期望的转换应该生效。
这是因为imageView在片段中...它不是Activity B的元素..所以在
活动B你可以做这样的事情并测试它..
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_to_fragment);
FrameLayout frame = (FrameLayout) findViewById(R.id.content);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
frame
.setTransitionName(getString(R.string.simple_activity_transition));
}
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.content, FragmentB.newInstance())
.commit();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
现在你可以测试一下,即使是onBackPressed
也会有过渡。
以上是关于不同活动的片段之间的共享元素转换的主要内容,如果未能解决你的问题,请参考以下文章