androidandroid-fragmentsandroid-animationandroid-navigationandroid-transitions

only android.R.transition.move not working


I was trying to add shared element transition to my fragments but move transition doesn't work

val transition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)

if i change android.R.transition.move to android.R.transition.explode or android.R.transition.slide_left animation will work but not the ones that are needed

i use navigation library

first fragment code:

class TimersListFragment : Fragment() {
    private lateinit var binding: FragmentTimersListBinding
    private lateinit var viewModel: TimerListViewModel

    private lateinit var setListAdapter: SetListAdapter

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        binding = FragmentTimersListBinding.inflate(inflater)
        viewModel = ViewModelProvider(this).get(TimerListViewModel::class.java)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        super.onStart()

        setListAdapter = SetListAdapter()

        setListAdapter.onItemClicked = { set, name, time ->
                val extras = FragmentNavigatorExtras(name to "setName", time to "setTime")
                val action = TimersListFragmentDirections.previewSet(set.setInfo.setId)
                findNavController().navigate(action,extras)
        }
        binding.listSets.layoutManager = LinearLayoutManager(context)
        binding.listSets.adapter = setListAdapter
    }
}

recyclerView item layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_set_info"

        style="@style/CardView.rounded"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:clickable="true"
        android:focusable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:id="@+id/item_card_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?android:attr/selectableItemBackground">

                <TextView
                    android:id="@+id/text_set_name"
                    android:transitionName="setName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="16dp"
                    android:layout_marginStart="16dp"
                    android:layout_marginTop="16dp"
                    android:textAppearance="@style/TextAppearance.AppCompat.Headline"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="set name" />

                <TextView
                    android:id="@+id/text_approximate_time"
                    android:transitionName="setTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:layout_marginBottom="16dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="@+id/text_set_name"
                    app:layout_constraintTop_toBottomOf="@+id/text_set_name"
                    tools:text="TextView" />
            </androidx.constraintlayout.widget.ConstraintLayout>
        </LinearLayout>

    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

second fragment code:

class SetPreviewFragment : Fragment() {

    private lateinit var binding: FragmentSetPreviewBinding
    private lateinit var viewmodel: SetPreviewViewModel
    private val args: SetPreviewFragmentArgs by navArgs()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        viewmodel = ViewModelProvider(this).get(SetPreviewViewModel::class.java)
        viewmodel.setup(args.setId)
        binding = FragmentSetPreviewBinding.inflate(inflater)
        return binding.root
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val transition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
        sharedElementEnterTransition = transition
        sharedElementReturnTransition = transition
    }
}

second fragment layout:

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/motion_layout_preview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/fragment_set_preview_scene"
    tools:context=".screens.SetPreviewFragment">


    <androidx.appcompat.widget.Toolbar
        android:id="@+id/preview_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:title="@string/set_preview"
        app:titleTextColor="?attr/colorOnPrimary" />

    <TextView
        android:id="@+id/text_set_name_title"
        android:transitionName="setName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:elevation="2dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/preview_toolbar"
        tools:text="set name" />

    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"

        android:layout_marginBottom="8dp"
        app:cardCornerRadius="25dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_p_start">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_p_action_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:listitem="@layout/item_preview_action" />
    </androidx.cardview.widget.CardView>

    <Button
        android:id="@+id/btn_p_start"
        style="@style/RoundedButton50dp"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:gravity="start|center_vertical"
        android:paddingHorizontal="16dp"
        android:text="@string/start"
        app:layout_constraintEnd_toStartOf="@+id/btn_p_edit"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_set_name_title" />

    <TextView
        android:id="@+id/text_time_on_button"
        android:transitionName="setTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:elevation="2dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Button"
        android:textColor="?attr/colorOnPrimary"
        android:translationZ="2dp"
        app:layout_constraintBottom_toBottomOf="@+id/btn_p_start"
        app:layout_constraintEnd_toEndOf="@+id/btn_p_start"
        app:layout_constraintTop_toTopOf="@+id/btn_p_start"
        tools:text="00:00" />

    <ImageButton
        android:id="@+id/btn_p_edit"
        style="@style/RoundedButton50dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:backgroundTint="?attr/colorPrimary"
        android:minWidth="50dp"
        android:minHeight="50dp"
        android:paddingHorizontal="12dp"
        android:src="@drawable/ic_edit"
        android:tint="?attr/colorOnPrimary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_set_name_title" />

</androidx.constraintlayout.motion.widget.MotionLayout>

Solution

  • I face the same situation, trying to perform shared element transitions from a RecyclerView and make it work by setting a unique transitionName by code.

    the unique transitionName that I use was the content of the element. maybe you can try by using the name and/or the time directly.