Zaimplementowałem przejście elementu współużytkowanego między obrazem z widoku RecyclerView a obrazem w nowym Fragmentie. RecyclerView jest hostowany w fragmencie obsługiwanym przez działanie, a fragment docelowy jest hostowany wewnątrz innego działania.Udostępnione przejście elementów nie ma oczekiwanego zachowania
Kiedy klikam na moim obrazku, przejście dzieje się tak, jak powinno, i dostaję się do mojego fragmentu. Ale kiedy klikam przycisk Wstecz, przejście próbuje umieścić mój obraz na pierwszej pozycji mojego RecyclerView, podczas gdy aktualnie wyświetla obraz, który niekoniecznie jest pierwszym.
Z tej sytuacji pomyślałem, ponieważ jest to lista obrazów, w których ustawiam nazwę przejścia wewnątrz kodu XML, być może po powrocie, ponieważ wszystkie obrazy mają tę samą nazwę przejścia, proces jest mylony i po prostu pierwsze obraz o podanej nazwie. Więc może powinienem dynamicznie nadać każdemu z nich inną nazwę przejścia. Ustawię tę samą nazwę dla obrazu docelowego i resetuję ją za każdym razem, gdy wybierany jest nowy obraz. Ale wciąż nie działa. Czy ktoś może mi w tym pomóc?
Oto kod w moim onItemClickListener:
mAdapter.setOnItemClickListener(new RssItemAdapter.OnItemCLickListener(){
@Override
public void onItemClick(View view, int position) {
final RssItem item = mAdapter.getItem(position);
final RssElementIntent intent = new RssElementIntent(getActivity(), item, position);
// mRootView is the view of the fragment
final ImageView image = (ImageView)
mRootView.findViewById(R.id.rss_element_image);
image.setTransitionName(getString(R.string.transition_name_rss_feed_picture) + position);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(), image, RssElementFragment.EXTRA_IMAGE);
ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
}
});
Oto kod we fragmencie docelowego:
rssImage.setTransitionName(getString(R.string.transition_name_rss_feed_picture) + getArguments().getInt(ARG_ELEMENT_POSITION));
ViewCompat.setTransitionName(rssImage, EXTRA_IMAGE);
A oto themes.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/theme_primary</item>
<item name="colorPrimaryDark">@color/theme_primary_dark</item>
<item name="android:colorAccent">@color/theme_accent</item>
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform
</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform
</item>
</style>
Edytuj:
Znalazłem swój błąd, otrzymałem ImageView z fragmentu rootView, który dawał mi losowy obraz z mojego widoku RecyclerView, co oznacza złą nazwę przejścia. Więc użyłem widoku podanego przez onItemClick i działało! Przenoszę również setTransitionName()
do adaptera.
mAdapter.setOnItemClickListener(new RssItemAdapter.OnItemCLickListener(){
@Override
public void onItemClick(View view, int position) {
final RssItem item = mAdapter.getItem(position);
final RssElementIntent intent = new RssElementIntent(getActivity(), item, position);
// WRONG !
// final ImageView image = (ImageView) mRootView.findViewById(R.id.rss_element_image);
// Correct
final ImageView image = (ImageView) view.findViewById(R.id.rss_element_image);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(), image, RssElementFragment.EXTRA_IMAGE);
ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
}
});
Myślę, że dodanie 'position' do nazwy przejścia może być uciążliwe, działa bez" pozycji "w moim przypadku. Może powinieneś spróbować usunąć 'position' w nazwie przejścia. – hidro
Próbowałem i nadal otrzymuję taki sam wynik ... –
W adapterze do widoku RecyclerView w obiekcie onBindViewHolder ustaw unikalny parametr transitionName w wierszu dla każdego możliwego elementu współużytkowanego. Zwykle pochodzi to z unikalnego identyfikatora pewnego rzędu, ale jeśli nie masz czegoś takiego, możesz użyć pozycji tak długo, jak nie zmieniasz kolejności. Po przejściu "wstecz" widok jest przeszukiwany według nazwy przejścia. Jeśli nie masz możliwości unikalnego identyfikowania w czasie wiązania, możesz zastąpić onMapSharedElements, aby nadać ramie wskazówki, których potrzebuje. –