Android 共享元素片段转换:return 转换无效
Android shared element fragment transitions: return transition not working
在我的项目中,我使用 RecyclerView
来显示带有缩略图的项目列表。当用户点击一个项目时,一个 DetailView 被打开,图像显示在顶部。我试图在这些片段之间共享一些元素,但是 只有在进入细节片段时过渡才起作用,从细节片段返回时不起作用。
在我的 ListAdapter
中,我设置了 TransitionName
并在用户单击某个项目时通知 ListFragment:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
viewHolder.image.setTag(Constants.SHARED_NAME_IMAGE + item.itemId);
}
点击事件:
@OnClick(R.id.root)
public void onClickedItem() {
List<Pair<View, String>> sharedElements = new ArrayList<>();
sharedElements.add(new Pair<View, String>(image, (String) image.getTag()));
interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);
}
然后在 ListFragment 中启动 DetailFragment:
public void navigateToFragment(Fragment curFragment, Fragment nextFragment,
boolean addToBackStack, List<Pair<View, String>> sharedElements) {
if (nextFragment == null) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && sharedElements != null && curFragment != null) {
// Setup transition on first fragment
curFragment.setSharedElementEnterTransition(TransitionUtil.getReturnTransition(this));
curFragment.setSharedElementReturnTransition(TransitionUtil.getEnterTransition(this));
curFragment.setEnterTransition(null);
curFragment.setExitTransition(null);
// Setup transition on second fragment
nextFragment.setSharedElementEnterTransition(TransitionUtil.getEnterTransition(this));
nextFragment.setSharedElementReturnTransition(TransitionUtil.getReturnTransition(this));
nextFragment.setEnterTransition(null);
nextFragment.setExitTransition(null);
// Add second fragment by replacing first
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, nextFragment);
if (addToBackStack) {
ft.addToBackStack("fragment");
}
for (Pair<View, String> sharedElement : sharedElements) {
ViewCompat.setTransitionName(sharedElement.first, sharedElement.second);
ft.addSharedElement(sharedElement.first, sharedElement.second);
}
// Apply the transaction
ft.commit();
} else {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, nextFragment);
if (addToBackStack) {
ft.addToBackStack("fragment");
}
ft.commit();
}
}
最后,我在 DetailFragment 的 onCreateView()
中设置当前转换名称(因为它取决于 itemId):
ViewCompat.setTransitionName(header, Constants.SHARED_NAME_IMAGE + itemId);
我刚刚解决了这个问题:有 2 个问题:
- 我已经覆盖了我的列表适配器(因此转换名称已被删除)
- 我还没有在
onBindViewHolder
中设置转换名称
为了解决 #1,我像这里一样更改了 setUpList(){...}
(第一个 if 很重要!):
private void setupList() {
if (adapter != null) {
list.setAdapter(adapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
list.setLayoutManager(linearLayoutManager);
setScrollListener();
return;
}
refreshLayout.setColorSchemeColors(ResourcesCompat.getColor(getResources(), R.color.main_color_2, getActivity().getTheme()));
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
loadList(true);
}
});
adapter = new ListAdapter((int) (DisplayUtils.getWidth(getActivity()) * 0.6), this);
list.setAdapter(adapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
list.setLayoutManager(linearLayoutManager);
refreshLayout.post(new Runnable() {
@Override
public void run() {
refreshLayout.setRefreshing(true);
loadFilterItems();
为了解决#2,我只是将 setTag(..)
替换为 setTransitionName(..)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
vh.image.setTransitionName(Constants.SHARED_NAME_IMAGE + item.itemId);
}
在我的 onClick 方法中:
List<Pair<View, String>> sharedElements = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
sharedElements.add(new Pair<View, String>(image, image.getTransitionName()));
}
interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);
在我的项目中,我使用 RecyclerView
来显示带有缩略图的项目列表。当用户点击一个项目时,一个 DetailView 被打开,图像显示在顶部。我试图在这些片段之间共享一些元素,但是 只有在进入细节片段时过渡才起作用,从细节片段返回时不起作用。
在我的 ListAdapter
中,我设置了 TransitionName
并在用户单击某个项目时通知 ListFragment:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
viewHolder.image.setTag(Constants.SHARED_NAME_IMAGE + item.itemId);
}
点击事件:
@OnClick(R.id.root)
public void onClickedItem() {
List<Pair<View, String>> sharedElements = new ArrayList<>();
sharedElements.add(new Pair<View, String>(image, (String) image.getTag()));
interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);
}
然后在 ListFragment 中启动 DetailFragment:
public void navigateToFragment(Fragment curFragment, Fragment nextFragment,
boolean addToBackStack, List<Pair<View, String>> sharedElements) {
if (nextFragment == null) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && sharedElements != null && curFragment != null) {
// Setup transition on first fragment
curFragment.setSharedElementEnterTransition(TransitionUtil.getReturnTransition(this));
curFragment.setSharedElementReturnTransition(TransitionUtil.getEnterTransition(this));
curFragment.setEnterTransition(null);
curFragment.setExitTransition(null);
// Setup transition on second fragment
nextFragment.setSharedElementEnterTransition(TransitionUtil.getEnterTransition(this));
nextFragment.setSharedElementReturnTransition(TransitionUtil.getReturnTransition(this));
nextFragment.setEnterTransition(null);
nextFragment.setExitTransition(null);
// Add second fragment by replacing first
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, nextFragment);
if (addToBackStack) {
ft.addToBackStack("fragment");
}
for (Pair<View, String> sharedElement : sharedElements) {
ViewCompat.setTransitionName(sharedElement.first, sharedElement.second);
ft.addSharedElement(sharedElement.first, sharedElement.second);
}
// Apply the transaction
ft.commit();
} else {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, nextFragment);
if (addToBackStack) {
ft.addToBackStack("fragment");
}
ft.commit();
}
}
最后,我在 DetailFragment 的 onCreateView()
中设置当前转换名称(因为它取决于 itemId):
ViewCompat.setTransitionName(header, Constants.SHARED_NAME_IMAGE + itemId);
我刚刚解决了这个问题:有 2 个问题:
- 我已经覆盖了我的列表适配器(因此转换名称已被删除)
- 我还没有在
onBindViewHolder
中设置转换名称
为了解决 #1,我像这里一样更改了 setUpList(){...}
(第一个 if 很重要!):
private void setupList() {
if (adapter != null) {
list.setAdapter(adapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
list.setLayoutManager(linearLayoutManager);
setScrollListener();
return;
}
refreshLayout.setColorSchemeColors(ResourcesCompat.getColor(getResources(), R.color.main_color_2, getActivity().getTheme()));
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
loadList(true);
}
});
adapter = new ListAdapter((int) (DisplayUtils.getWidth(getActivity()) * 0.6), this);
list.setAdapter(adapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
list.setLayoutManager(linearLayoutManager);
refreshLayout.post(new Runnable() {
@Override
public void run() {
refreshLayout.setRefreshing(true);
loadFilterItems();
为了解决#2,我只是将 setTag(..)
替换为 setTransitionName(..)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
vh.image.setTransitionName(Constants.SHARED_NAME_IMAGE + item.itemId);
}
在我的 onClick 方法中:
List<Pair<View, String>> sharedElements = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
sharedElements.add(new Pair<View, String>(image, image.getTransitionName()));
}
interactionListener.onItemSelected(data.get(getAdapterPosition() - headerItemCount).type, data.get(getAdapterPosition() - headerItemCount).itemId, sharedElements);