Fragment Shared Element showing abnormal behaviour

2019-08-09 07:18发布

问题:

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.

回答1:

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>