两个 recyclerView 之间的 makeSceneTransitionAnimation 仅反向工作
makeSceneTransitionAnimation between two recyclerViews working only in reverse
简而言之:
创建共享元素 activity 片段与 recyclerView onClick 打开 activity 与另一个 recylcerView 之间的转换不会触发转换。
但是,使用 supportFinishAfterTransition();
关闭打开的 Activity 确实 正确触发动画(倒退到之前的 activity) .
此外,在 recyclerView 外部 创建共享元素将使动画在每种情况下都能正常工作(完成时向前和向后) - 因此我的代码必须是正确的。
带有打开 Activity 的 OnClickListener 的 Viewholder - 简化以减少无用代码。
public class StatsViewHolder extends WebStatsViewHolder implements View.OnClickListener{
protected TextView vTitle;
protected ImageView vPicture;
public StatsViewHolder (View itemView) {
super(itemView);
vTitle = (TextView) itemView.findViewById(R.id.stats_title);
vPicture = (ImageView) itemView.findViewById(R.id.stats_picture);
vTitle.setClickable(true);
vTitle.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(v, getLayoutPosition(), v.getRootView());
}
}
}
点击标题打开新的activity。 - 除非我将目标放在回收站之外,否则动画不会触发
mAdapter.SetOnItemClickListener(new MySteamWebStatsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position, View parent) {
Intent intent = new Intent(getActivity(), Details.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(), parent.findViewById(R.id.stats_picture), "stats_picture");
startActivity(intent, options.toBundle());
}
原来我是个笨蛋,留下这个以防有人犯同样的错误。
在目标 recyclerView
中,我使用 Picasso 加载可绘制对象 - Picasso 加载图像所需的时间恰好是动画所用的时间,因此它没有显示出来。这也是动画反向工作的原因 - 图像已经缓存。
如何解决问题:
等到图像加载完毕 - 我在 onCreate
中调用了这个
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
postponeEnterTransition();
}
加载图像时请求来自 Picasso 的回调
Picasso.with(this).load(mapObject.getDrawable()).transform(new CircleTransform()).fit().centerCrop().into(detailPicture, new Callback() {
@Override
public void onSuccess() {
scheduleStartPostponedTransition(detailPicture);
}
@Override
public void onError() {
}
});
开始动画
private void scheduleStartPostponedTransition(final View sharedElement) {
sharedElement.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
简而言之:
创建共享元素 activity 片段与 recyclerView onClick 打开 activity 与另一个 recylcerView 之间的转换不会触发转换。
但是,使用 supportFinishAfterTransition();
关闭打开的 Activity 确实 正确触发动画(倒退到之前的 activity) .
此外,在 recyclerView 外部 创建共享元素将使动画在每种情况下都能正常工作(完成时向前和向后) - 因此我的代码必须是正确的。
带有打开 Activity 的 OnClickListener 的 Viewholder - 简化以减少无用代码。
public class StatsViewHolder extends WebStatsViewHolder implements View.OnClickListener{
protected TextView vTitle;
protected ImageView vPicture;
public StatsViewHolder (View itemView) {
super(itemView);
vTitle = (TextView) itemView.findViewById(R.id.stats_title);
vPicture = (ImageView) itemView.findViewById(R.id.stats_picture);
vTitle.setClickable(true);
vTitle.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(v, getLayoutPosition(), v.getRootView());
}
}
}
点击标题打开新的activity。 - 除非我将目标放在回收站之外,否则动画不会触发
mAdapter.SetOnItemClickListener(new MySteamWebStatsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position, View parent) {
Intent intent = new Intent(getActivity(), Details.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(), parent.findViewById(R.id.stats_picture), "stats_picture");
startActivity(intent, options.toBundle());
}
原来我是个笨蛋,留下这个以防有人犯同样的错误。
在目标 recyclerView
中,我使用 Picasso 加载可绘制对象 - Picasso 加载图像所需的时间恰好是动画所用的时间,因此它没有显示出来。这也是动画反向工作的原因 - 图像已经缓存。
如何解决问题:
等到图像加载完毕 - 我在 onCreate
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
postponeEnterTransition();
}
加载图像时请求来自 Picasso 的回调
Picasso.with(this).load(mapObject.getDrawable()).transform(new CircleTransform()).fit().centerCrop().into(detailPicture, new Callback() {
@Override
public void onSuccess() {
scheduleStartPostponedTransition(detailPicture);
}
@Override
public void onError() {
}
});
开始动画
private void scheduleStartPostponedTransition(final View sharedElement) {
sharedElement.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}