I am trying to open a fragment by clicking on floating action button using material container transform animation. I have implemented the animation but it is not working as I expected.
When navigating from one fragment A to Fragment B, the floating action button is still visible (enlarged for a brief second) when Fragment B is being opened.
What changes do I make in the animation so that the transition from floating action button to Fragment B feels more smooth? or How do I hide the enlarged floating action button when navigating to Fragment B? Below is the code of Fragments and layouts for reference.
Fragment A layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.home.HomeFragment">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@ id/create_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:transitionName="my_transition"
android:src="@drawable/ic_round_add_24"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/dimen_16"
android:contentDescription="New Task"
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Fragment A code:
class FragmentA : Fragment() {
private var _binding: FragmentABinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = Hold()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentABinding.inflate(inflater)
binding.createTask.setOnClickListener {
val extras = FragmentNavigatorExtras(binding.createTask to "my_transition")
findNavController().navigate(R.id.action_FragmentA_to_FragmentB,null,null,extras)
}
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Fragment B layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:transitionName="my_transition"
tools:context=".ui.edit.EditTaskFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_size"
app:liftOnScroll="true">
<FrameLayout
android:layout_width="match_parent"
android:paddingHorizontal="@dimen/dimen_16"
android:layout_height="match_parent">
<ImageButton
android:id="@ id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_close_24"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_gravity="start|center_vertical"
app:tint="?attr/colorPrimary" />
<com.google.android.material.button.MaterialButton
android:id="@ id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
style="@style/Widget.Material3.Button.TonalButton"
android:text="Save"
android:minWidth="0dp"
android:minHeight="0dp"/>
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
android:textAlignment="center"
android:text="This is new Fragment"/>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Fragment B code:
class FragmentB : Fragment() {
private var _binding: FragmentBBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedElementEnterTransition = MaterialContainerTransform()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentBBinding.inflate(inflater)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
CodePudding user response:
Solved the problem!! Just set startContainerColor and endContainerColor parameter in materialContainerTransform to surface color and then the fab transition is done more smoothly
Replace sharedElementEnterTransition in FragmentB with this:
sharedElementEnterTransition = MaterialContainerTransform().apply {
startContainerColor = requireContext().getColorFromAttr(com.google.android.material.R.attr.colorSurface)
endContainerColor = requireContext().getColorFromAttr(com.google.android.material.R.attr.colorSurface)
}