SharedElements 在 RecyclerView 中的不良影响
SharedElements undesirable effect in RecyclerView
我有一个 activity,带有一个 RecyclerView(SuperSlim 库)和一个详细信息 activity,当我单击该列表中的一个项目时,详细信息 activity 将打开。问题是当我返回时,我试图将点击的元素设置为列表中的第一个可见元素,但我得到了这个可怕的动画:
这是我的 onActivityReenter()
@Override
public void onActivityReenter(int resultCode, Intent data) {
super.onActivityReenter(resultCode, data);
Log.d(TAG, "onActivityReenter() called with: resultCode = [" + resultCode + "], data = [" + data + "]");
mTmpReenterState = new Bundle(data.getExtras());
int startingPosition = mTmpReenterState.getInt(EXTRA_STARTING_ITEM_POSITION);
int currentPosition = mTmpReenterState.getInt(EXTRA_CURRENT_ITEM_POSITION);
mRecycler.scrollToPosition(currentPosition);
postponeEnterTransition();
mRecycler.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mRecycler.getViewTreeObserver().removeOnPreDrawListener(this);
// TODO: figure out why it is necessary to request layout here in order to get a smooth transition.
mRecycler.requestLayout();
startPostponedEnterTransition();
return true;
}
});
}
还有我的 SharedElementCallback:
private final SharedElementCallback exitTransitionCallBack = new SharedElementCallback() {
@Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
if (mTmpReenterState == null) {
// If mTmpReenterState is null, then the activity is exiting.
View navigationBar = findViewById(android.R.id.navigationBarBackground);
View statusBar = findViewById(android.R.id.statusBarBackground);
if (navigationBar != null) {
names.add(navigationBar.getTransitionName());
sharedElements.put(navigationBar.getTransitionName(), navigationBar);
}
if (statusBar != null) {
names.add(statusBar.getTransitionName());
sharedElements.put(statusBar.getTransitionName(), statusBar);
}
} else {
int startingPosition = mTmpReenterState.getInt(EXTRA_STARTING_ITEM_POSITION);
int currentPosition = mTmpReenterState.getInt(EXTRA_CURRENT_ITEM_POSITION);
if (startingPosition != currentPosition) {
// If startingPosition != currentPosition the user must have swiped to a
// different page in the DetailsActivity. We must update the shared element
// so that the correct one falls into place.
sharedElements.clear();
sharedElements.put("number", mLayoutManager.findViewByPosition(currentPosition).findViewById(R.id.text_number));
sharedElements.put("day", mLayoutManager.findViewByPosition(currentPosition).findViewById(R.id.text_day));
sharedElements.put("recycler", mLayoutManager.findViewByPosition(currentPosition + 1).findViewById(R.id.recycler));
}
mTmpReenterState = null;
}
}
};
我认为问题在于 activity 尝试制作从原始项目位置到列表顶部的动画,但我不知道如何避免这种情况。
有谁知道如何解决这个问题?
提前谢谢大家!!!
一段时间后,我意识到我正在用 LocalBroadcast
的 notifyItemChanged(int)
和标准 recyclerView
动画更新主要 Activity 列表的问题那个故障。我使用以下方法解决问题:
RecyclerView.setItemAnimator(null)
因为标准不起作用
((SimpleItemAnimator) RecyclerView.getItemAnimator())
.setSupportsChangeAnimations(false)
所以问题与SharedElements
无关。
我有一个 activity,带有一个 RecyclerView(SuperSlim 库)和一个详细信息 activity,当我单击该列表中的一个项目时,详细信息 activity 将打开。问题是当我返回时,我试图将点击的元素设置为列表中的第一个可见元素,但我得到了这个可怕的动画:
这是我的 onActivityReenter()
@Override
public void onActivityReenter(int resultCode, Intent data) {
super.onActivityReenter(resultCode, data);
Log.d(TAG, "onActivityReenter() called with: resultCode = [" + resultCode + "], data = [" + data + "]");
mTmpReenterState = new Bundle(data.getExtras());
int startingPosition = mTmpReenterState.getInt(EXTRA_STARTING_ITEM_POSITION);
int currentPosition = mTmpReenterState.getInt(EXTRA_CURRENT_ITEM_POSITION);
mRecycler.scrollToPosition(currentPosition);
postponeEnterTransition();
mRecycler.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mRecycler.getViewTreeObserver().removeOnPreDrawListener(this);
// TODO: figure out why it is necessary to request layout here in order to get a smooth transition.
mRecycler.requestLayout();
startPostponedEnterTransition();
return true;
}
});
}
还有我的 SharedElementCallback:
private final SharedElementCallback exitTransitionCallBack = new SharedElementCallback() {
@Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
if (mTmpReenterState == null) {
// If mTmpReenterState is null, then the activity is exiting.
View navigationBar = findViewById(android.R.id.navigationBarBackground);
View statusBar = findViewById(android.R.id.statusBarBackground);
if (navigationBar != null) {
names.add(navigationBar.getTransitionName());
sharedElements.put(navigationBar.getTransitionName(), navigationBar);
}
if (statusBar != null) {
names.add(statusBar.getTransitionName());
sharedElements.put(statusBar.getTransitionName(), statusBar);
}
} else {
int startingPosition = mTmpReenterState.getInt(EXTRA_STARTING_ITEM_POSITION);
int currentPosition = mTmpReenterState.getInt(EXTRA_CURRENT_ITEM_POSITION);
if (startingPosition != currentPosition) {
// If startingPosition != currentPosition the user must have swiped to a
// different page in the DetailsActivity. We must update the shared element
// so that the correct one falls into place.
sharedElements.clear();
sharedElements.put("number", mLayoutManager.findViewByPosition(currentPosition).findViewById(R.id.text_number));
sharedElements.put("day", mLayoutManager.findViewByPosition(currentPosition).findViewById(R.id.text_day));
sharedElements.put("recycler", mLayoutManager.findViewByPosition(currentPosition + 1).findViewById(R.id.recycler));
}
mTmpReenterState = null;
}
}
};
我认为问题在于 activity 尝试制作从原始项目位置到列表顶部的动画,但我不知道如何避免这种情况。
有谁知道如何解决这个问题?
提前谢谢大家!!!
一段时间后,我意识到我正在用 LocalBroadcast
的 notifyItemChanged(int)
和标准 recyclerView
动画更新主要 Activity 列表的问题那个故障。我使用以下方法解决问题:
RecyclerView.setItemAnimator(null)
因为标准不起作用
((SimpleItemAnimator) RecyclerView.getItemAnimator())
.setSupportsChangeAnimations(false)
所以问题与SharedElements
无关。