Search code examples
androidfragmentsharedelementandroid-transitions

Fragment Shared Element showing abnormal behaviour in transition


Here is my code:

DetailsFragment  fragment = new DetailsFragment();
Transition changeTransform = TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform);

Transition explodeTransform = TransitionInflater.from(getActivity()).
            inflateTransition(android.R.transition.explode);

setSharedElementReturnTransition(changeTransform);
setExitTransition(explodeTransform);

// Setup enter transition on second fragment
fragment.setSharedElementEnterTransition(changeTransform);
fragment.setEnterTransition(explodeTransform);
FragmentManager manager = ((Activity)mContext).getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.layoutView, fragment).addToBackStack(fragment.getClass().getSimpleName())
.addSharedElement(view.findViewById(R.id.itemView), "view");
fragment.commit();

In DetailsFragment giving the same transition name("view" as Assign a Common Transition Name) in Layout for ImageView but I not able to see any transition on Android Lollipop.

I have already declared the manifests file style for (Enable Window Content Transitions) -

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowContentTransitions">true</item>
</style>

I have searched a lot but didn't get answer.


Solution

  • First need to Create

    • transition directory under project res directory.
    • Create change_image_trans.xml under transition directory.

       <?xml version="1.0" encoding="utf-8"?>
       <transitionSet>
           <changeTransform/>
          <changeBounds/>
       </transitionSet>
      

    Activity like this -

     public class DemoActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);
    
        ListFragment listFragment = new ListFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, listFragment)
                .commit();
    }
     }
    

    My Activity fragment like this -

    activity_fragment.xml

     <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    </LinearLayout>
    
     </LinearLayout>
    

    here is my fragment to open -

    ListFragment.java

     public class ListFragment extends Fragment implements AbsListView.OnItemClickListener {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_list, container, false);
    
            ListView listView = (ListView) view.findViewById(R.id.listView);
            String [] strings = {"First Element", "Second Element", "Third Element"};
            MyListAdapter myListAdapter = new MyListAdapter(getActivity(), R.layout.list_item, strings);
            listView.setAdapter(myListAdapter);
    
            listView.setOnItemClickListener(this);
    
            return view;
        }
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String imageTransitionName = "";
            String textTransitionName = "";
    
            ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
            TextView textView = (TextView) view.findViewById(R.id.textView);
    
            ImageView staticImage = (ImageView) getView().findViewById(R.id.imageView);
    
            LastFragment lastFragment = new LastFragment();
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                setSharedElementReturnTransition(TransitionInflater.from(
                        getActivity()).inflateTransition(R.transition.change_image_trans));
                setExitTransition(TransitionInflater.from(
                        getActivity()).inflateTransition(android.R.transition.fade));
    
                lastFragment.setSharedElementEnterTransition(TransitionInflater.from(
                        getActivity()).inflateTransition(R.transition.change_image_trans));
                lastFragment.setEnterTransition(TransitionInflater.from(
                        getActivity()).inflateTransition(android.R.transition.fade));
    
                imageTransitionName = imageView.getTransitionName();
                textTransitionName = textView.getTransitionName();
            }
    
            Bundle bundle = new Bundle();
            bundle.putString("TRANS_NAME", imageTransitionName);
            bundle.putString("ACTION", textView.getText().toString());
            bundle.putString("TRANS_TEXT", textTransitionName);
            bundle.putParcelable("IMAGE", ((BitmapDrawable) imageView.getDrawable()).getBitmap());
            lastFragment.setArguments(bundle);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.container, lastFragment)
                    .addToBackStack("Payment")
                    .addSharedElement(imageView, imageTransitionName)
                    .addSharedElement(textView, textTransitionName)
                    .addSharedElement(staticImage, getString(R.string.fragment_image_trans))
                    .commit();
        }
    }
    
    //MyListAdapter for creating list item
    class MyListAdapter extends ArrayAdapter<String> {
    
        public MyListAdapter(Context context, int resource, String[] objects) {
            super(context, resource, objects);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            View view = convertView;
    
            if (view == null) {
                view = LayoutInflater.from(getContext()).inflate(R.layout.list_item, null);
            }
    
            String listItem = getItem(position);
    
            TextView textView = (TextView) view.findViewById(R.id.textView);
            textView.setText(listItem);
    
            ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
            imageView.setImageResource(R.drawable.logo);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                textView.setTransitionName("trans_text" + position);
                imageView.setTransitionName("trans_image" + position);
            }
    
            return view;
        }
    
    
    }
    

    fragment_list.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="80dp"
            android:src="@drawable/logo"
            android:transitionName="@string/fragment_image_trans"/>
    
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/imageView">
    
        </ListView>
    </RelativeLayout>
    

    LastFragment.java

    public class LastFragment extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            Bundle bundle = getArguments();
            String actionTitle = "DUMMY ACTION";
            Bitmap imageBitmap = null;
            String transText = "";
            String transitionName = "";
    
            if (bundle != null) {
                transitionName = bundle.getString("TRANS_NAME");
                actionTitle = bundle.getString("ACTION");
                imageBitmap = bundle.getParcelable("IMAGE");
                transText = bundle.getString("TRANS_TEXT");
            }
    
            getActivity().setTitle(actionTitle);
            View view = inflater.inflate(R.layout.fragment_last, container, false);
    
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                view.findViewById(R.id.listImage).setTransitionName(transitionName);
                view.findViewById(R.id.textView).setTransitionName(transText);
            }
    
            ((ImageView) view.findViewById(R.id.listImage)).setImageBitmap(imageBitmap);
            ((TextView) view.findViewById(R.id.textView)).setText(actionTitle);
    
            return view;
        }
    }
    

    R.layout.fragment_last

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="24dp"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/listImage"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:src="@drawable/logo"/>
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:text="Sample"
            android:textSize="24sp"/>
    
        <ImageView
            android:id="@+id/otherImage"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginTop="24dp"
            android:src="@drawable/logo"
            android:transitionName="@string/fragment_image_trans"/>
    </RelativeLayout>