Nic*_*ick 2 animation android transition android-activity shared-element-transition
I'm working on implementing a basic Activity transition animation with a shared element from a RecyclerView with a GridLayoutManager to a full screen details Activity screen. The animation works well under regular circumstances. So when clicking on an image in the grid it scales to the full screen image and on exiting the reverse happens. But if you press the power button and return to the app while the details screen is visible, Android seems to clear all registered shared element/transitions so the full screen image instead of scaling back into the grid it just fades out. I tried registering SharedElementCallbacks in both Activities which are called properly without the power button press but neither gets called after pressing the power button. I'd appreciate any suggestions to help solve this problem.
这些是我添加代码以支持共享元素转换的地方:
public class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.imageview) ImageView imageView;
private Item item;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setTag(this);
itemView.setOnClickListener(onItemClickListener);
}
@Override
public void onBind(int position) {
super.onBind(position);
this.item = list.get(position);
imageView.setTransitionName(item.getId());
Glide.with(imageView.getContext().getApplicationContext())
.load(item.getUrl())
.centerCrop()
.apply(RequestOptions.placeholderOf(new ColorDrawable(Color.BLACK)))
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageView);
}
public Item getItem() {
return item;
}
}
public class MyActivity extends AppCompatActivity {
...
public void setUp() {
...
adapter.setOnItemClickListener(view -> {
MyViewHolder viewHolder = (MyViewHolder)view.getTag();
View view = viewHolder.imageView;
Intent intent = new Intent(this, DetailsActivity.class);
intent.putExtra(Item.TAG, viewHolder.getItem());
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
this,
view,
view.getTransitionName());
startActivity(intent, options.toBundle());
});
...
}
}
public class DetailsActivity extends AppCompatActivity {
@BindView(R.id.imageview) ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
supportPostponeEnterTransition();
Bundle bundle = getIntent().getExtras();
Item item = (Item) bundle.getSerializable(Item.TAG);
imageView.setTransitionName(item.getId());
final RequestListener<Drawable> requestListener = new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
supportStartPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
supportStartPostponedEnterTransition();
return false;
}
};
Glide.with(getApplicationContext())
.load(item.getUrl())
.centerCrop()
.addListener(requestListener)
.into(imageView);
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我相信这是一个从 API 29 开始的错误
共享元素转换。它在 API < 29 和 Fragment-Fragment 转换中运行良好。
从ActivityA到ActivityB和返回ActivityB到ActivityA一切正常工作,除非您在ActivityB 上并在后台或锁定设备屏幕上发送您的应用程序,然后您来到打开ActivityB的应用程序,现在按后退按钮或返回到ActivityA丢失所有共享即使您已经覆盖了元素反向转换sharedElementReturnTransition
我发现了一个简单的技巧来解决这个问题,这使我们的转换无法正常工作 -
在发送ActivityB到后台时,它会调用活动的onPause() > onStop()生命周期方法,现在onStop()您可以在您的内部
检查以下条件,如果活动未完成且您的 API > 29,则将当前 Bundle 传入callActivityOnSaveInstanceState(),
Kotlin 代码 // 在您的 ActivityB 中覆盖此方法
override fun onStop() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q && !isFinishing) {
Instrumentation().callActivityOnSaveInstanceState(this, Bundle())
}
super.onStop()
}
Run Code Online (Sandbox Code Playgroud)
Java 代码 // 在您的 ActivityB 中覆盖此生命周期方法
@Override
protected void onStop() {
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.Q && !isFinishing()){
new Instrumentation().callActivityOnSaveInstanceState(this, new Bundle());
}
super.onStop();
}
Run Code Online (Sandbox Code Playgroud)
我希望它有帮助!