I'm working on a project where I need a transition between fragments using shared elements. I've tried nearly everything but the transition effect isn't working.
I have an activity called TimelineActivity and I have 2 fragments, a ListFragment that is dynamically added to the TimelineActivity, and a DetailFragment.
Whenever I click on an item in the ListView in the ListFragment, the fragment is being replaced by the DetailFragment.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fragment.setSharedElementEnterTransition(new ChangeBounds().setDuration(2000));
fragment.setEnterTransition(new ChangeBounds().setDuration(2000));
setExitTransition(new ChangeBounds().setDuration(2000));
fragment.setSharedElementReturnTransition(new ChangeBounds().setDuration(2000));
}
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
fragment.setAllowEnterTransitionOverlap(true);
fragment.setAllowReturnTransitionOverlap(true);
ft.replace(R.id.timeline_container, fragment);
ft.addSharedElement(view.findViewById(R.id.transition), "selectClientTransition");
ft.addToBackStack(null);
// Start the animated transition.
ft.commit();
}
In my listview_row.xml which is the layout for the listview I have:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition">
</LinearLayout>
and in my fragment_detail.xml I have the following:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition"
android:weightSum="12">
</LinearLayout>
I added this to my AppTheme
<item name="android:windowContentTransitions">true</item>
Just to be clear, the fragments are replaced, that's working fine, but without a changebounds effect. I'm really stuck here so anything is welcome.
Thanks in advance
You need to set unique transition name for each element in the list. Here's an example:
in adapter's getView method set transition name:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// your code...
sharedView.setTransitionName("transition_name_" + position);
}
in onItemClick method send transition name to DetailFragment:
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
View sharedView = v.findViewById(R.id.shared_view);
Bundle arguments = new Bundle();
arguments.putString(DetailFragment.TRANSITION_NAME, sharedView.getTransitionName());
fragment.setArguments(arguments);
// the rest of your code (replacing fragments, etc)...
}
in DetailFragment's onCreateView method set transition name to view:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// your code...
View sharedView = inflatedLayout.findViewById(R.id.shared_view);
sharedView.setTransitionName(getArguments().getString(TRANSITION_NAME))
}