Переходы между общими элементами — фрагменты

Я разместил свой образец приложения здесь: https://bitbucket.org/user1010/transitiondemo

Я следую шаблону master-detail в своем приложении. Главный фрагмент (MyRecyclerFragment/MyListFragment) показывает список текстовых представлений. Когда пользователь нажимает на любое из этих текстовых представлений, запускается фрагмент сведений (MyDetailsFragment). Фрагмент сведений имеет заголовок (такой же, как и тот, на который кликнул пользователь).

Я пытаюсь добиться следующего эффекта перехода:

  • Взорвать переход для выхода из представлений
  • Плавный переход для появляющихся представлений
  • Переход Move/Translation для TextView, который является общим для этих двух фрагментов

Проблемы:

  • Общий TextView исчезает, когда начинается переход. Но общий переход чудесным образом работает, если щелкнуть первый элемент списка.
  • Переход работает, если изменено расположение деталей. См. details.xml. Если я полностью удалю FrameLayout title_bar и поставлю TextView title прямым дочерним элементом корневого LinearLayout, переход общего элемента будет работать отлично.
  • Похоже, что эпицентр меняется для перехода return общего элемента. Например, если я нажму на 7-й TextView в списке, выходной переход (взрыв) возьмет этот TextView в качестве эпицентра. Все TextViews над ним скользят вверх, а TextViews под ним скользят вниз. Но при возврате из фрагмента деталей в мастер-фрагмент эпицентром обратного перехода является не тот TextView, который был нажат.



Ответы (2)


  • Общий TextView исчезает, когда начинается переход. Но общий переход чудесным образом работает, если щелкнуть первый элемент списка.
  • Переход работает, если изменено расположение деталей. См. файл details.xml. Если я полностью удалю заголовок FrameLayout и поставлю заголовок TextView прямым дочерним элементом корневого LinearLayout, переход общего элемента будет работать отлично.

Кажется, что детали TextView не могут быть анимированы за пределами его родительских границ. Попробуйте установить для clipChildren значение false для всех родительских представлений вашего TextView в файле details.xml следующим образом. Это работает для меня.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:clipChildren="false"
              android:orientation="vertical">

    <FrameLayout
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:clipChildren="false">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@android:color/white"
            android:gravity="center"
            android:text="@string/dummy_title"
            android:textColor="@android:color/black"/>
    </FrameLayout>
    ...
</LinearLayout>
person JFrite    schedule 08.09.2015

попробуй с этим -

установите изображение каждой строки с другим именем перехода -

 @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);
        }

        TextView textView = (TextView) view.findViewById(R.id.textView);

        ImageView imageView = (ImageView) view.findViewById(R.id.imageView);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            textView.setTransitionName("transtext" + position);
            imageView.setTransitionName("transition" + position);
        }

        return view;
    }
}

затем, например, нажмите на элемент -

 ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
            TextView textView = (TextView) view.findViewById(R.id.smallerImageView);

            EndFragment endFragment = new EndFragment();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

                imageTransitionName = imageView.getTransitionName();
                textTransitionName = textView.getTransitionName();



 setSharedElementReturnTransition(TransitionInflater.from(
                        getActivity()).inflateTransition(R.transition.change_image_trans));


  setExitTransition(TransitionInflater.from(
                    getActivity()).inflateTransition(android.R.transition.fade));

            endFragment.setSharedElementEnterTransition(TransitionInflater.from(
                    getActivity()).inflateTransition(R.transition.change_image_trans));
            endFragment.setEnterTransition(TransitionInflater.from(
                    getActivity()).inflateTransition(android.R.transition.fade));

            }

 Bundle bundle = new Bundle();

        FragmentManager fragmentManager = getFragmentManager();

            bundle.putString("TRANS_NAME", imageTransitionName);
            bundle.putString("TRANS_TEXT", textTransitionName);
            endFragment.setArguments(bundle);

            fragmentManager.beginTransaction()
                    .replace(R.id.container, endFragment)
                    .addToBackStack("Payment")
                    .addSharedElement(imageView, imageTransitionName)
                    .addSharedElement(textView, textTransitionName)
                    .addSharedElement(staticImage, getString(R.string.fragment_image_trans))
                    .commit();

В EndFragment в методе oncreate получите ключ имени перехода и установите его в представлении -

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Bundle bundle = getArguments();
        String actionTitle = "";
        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_end, container, false);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            view.findViewById(R.id.listImage).setTransitionName(transitionName);
            view.findViewById(R.id.smallerImageView).setTransitionName(transText);
        }

        ((ImageView) view.findViewById(R.id.listImage)).setImageBitmap(imageBitmap);
        ((TextView) view.findViewById(R.id.smallerImageView)).setText(actionTitle);

        return view;
    }

связанные https://stackoverflow.com/a/31982516/3150663

Проголосуйте за мой ответ, если у вас есть решение. :)

person Nitish Srivastava    schedule 13.08.2015
comment
Если эти два вопроса идентичны, то их следует закрыть как дубликаты. Если это не так, вы должны предоставить здесь полный ответ, а не ответ только по ссылке. - person josliber♦; 13.08.2015