5
AndroidStudio 2.3 Beta 1 

Я пытаюсь заставить переходы работать с фрагментами, как изображение, которое я использую, не переходит. Он просто появляется как обычно.sharedElment переход с использованием фрагментов непереход

Я создал простое приложение, чтобы попытаться заставить его работать. У меня есть 2 фрагмента ListMovieFragment и DetailMovieFragment. И 1 MainActivity.

Чтобы перейти на DetailMovieFragment, щелкните по изображению в ListMovieFragment.

Это мой переход XML change_image_transform:

<?xml version="1.0" encoding="utf-8"?> 
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 
    <changeImageTransform/> 
</transitionSet> 

ListMovieFragment:

public class ListMovieFragment extends Fragment { 
    public interface MovieSelectedListener { 
     void onMovieSelected(int movieId); 
    } 
    private MovieSelectedListener mMovieSelectedListener; 

    public ListMovieFragment() { 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     mMovieSelectedListener = (MovieSelectedListener)context; 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mMovieSelectedListener = null; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     final View view = inflater.inflate(R.layout.fragment_list, container, false); 
     final ImageView ivMoviePoster = (ImageView)view.findViewById(R.id.ivMoviePoster); 

     ivMoviePoster.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if(mMovieSelectedListener != null) { 
        mMovieSelectedListener.onMovieSelected(12345); 
       } 
      } 
     }); 

     Glide.with(getActivity()) 
       .load("https://image.tmdb.org/t/p/w185/qjiskwlV1qQzRCjpV0cL9pEMF9a.jpg") 
       .placeholder(R.drawable.placeholder_poster) 
       .centerCrop() 
       .crossFade() 
       .into(ivMoviePoster); 

     return view; 
    } 
} 

DetailMovieFragment

public class DetailMovieFragment extends Fragment { 
    public DetailMovieFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     final View view = inflater.inflate(R.layout.fragment_detail, container, false); 

     final ImageView ivMovieDetailPoster = (ImageView)view.findViewById(R.id.ivMovieDetailPoster); 

     Glide.with(getActivity()) 
       .load("https://image.tmdb.org/t/p/w185/qjiskwlV1qQzRCjpV0cL9pEMF9a.jpg") 
       .placeholder(R.drawable.placeholder_poster) 
       .centerCrop() 
       .crossFade() 
       .into(ivMovieDetailPoster); 

     return view; 
    } 
} 

MainActivity

public class MainActivity extends AppCompatActivity implements ListMovieFragment.MovieSelectedListener { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if(savedInstanceState == null) { 
      FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.add(R.id.activity_main, new ListMovieFragment(), "listmoviefragment"); 
      fragmentTransaction.commit(); 
     } 
    } 

    @Override 
    public void onMovieSelected(int movieId) { 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      /* Get the fragments that will be using the transition */ 
      ListMovieFragment listMovieFragment = new ListMovieFragment(); 
      DetailMovieFragment detailMovieFragment = new DetailMovieFragment(); 

      /* Inflate the transition */ 
      Transition changeTransition = TransitionInflater 
        .from(MainActivity.this) 
        .inflateTransition(R.transition.change_image_transform); 

      Transition explodeTransition = TransitionInflater 
        .from(MainActivity.this) 
        .inflateTransition(android.R.transition.explode); 

      /* Set the exit and return on the source fragment (ListMovieFragment) */ 
      listMovieFragment.setSharedElementReturnTransition(changeTransition); 
      listMovieFragment.setExitTransition(explodeTransition); 

      /* Set the enter on the destination fragment (MovieDetailFragment) */ 
      detailMovieFragment.setSharedElementEnterTransition(changeTransition); 
      detailMovieFragment.setEnterTransition(explodeTransition); 

      /* Get the shared imageview from the source fragment (MovieListFragment) */ 
      final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster); 

      FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment"); 
      fragmentTransaction.addToBackStack("detailmoviefragment"); 
      fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image)); 
      fragmentTransaction.commit(); 
     } 
     else { 
      FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment"); 
      fragmentTransaction.addToBackStack("detailmoviefragment"); 
      fragmentTransaction.commit(); 
     } 
    } 

    @Override 
    public void onBackPressed() { 
     if(getSupportFragmentManager().getBackStackEntryCount() > 0) { 
      getSupportFragmentManager().popBackStackImmediate(); 
     } 
     else { 
      super.onBackPressed(); 
     } 
    } 
} 

Схема для ListMovieFragment

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:paddingBottom="6dp"> 

    <ImageView 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/ivMoviePoster" 
     android:layout_width="match_parent" 
     android:layout_height="300dp" 
     android:src="@drawable/placeholder_poster" 
     android:scaleType="fitXY" 
     android:adjustViewBounds="true" 
     android:transitionName="@string/transition_poster_image"> 
    </ImageView> 
</LinearLayout> 

Макет для DetailMovieFragment:

<FrameLayout 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" 
    tools:context="me.androidbox.fragmenttransitions.detail.DetailMovieFragment"> 
    <ImageView 
     android:id="@+id/ivMovieDetailPoster" 
     android:layout_width="140dp" 
     android:layout_height="160dp" 
     android:layout_marginEnd="16dp" 
     android:layout_marginTop="112dp" 
     android:adjustViewBounds="true" 
     android:scaleType="fitXY" 
     android:layout_gravity="end" 
     android:transitionName="@string/transition_poster_image"/> 
</FrameLayout> 

Имя строки для имени перехода:

<string name="transition_poster_image">imagePoster</string> 

Реализация кажется простым, так что я думаю, что моя ошибка в том, что-то я не замечаю.

Большое спасибо за любые предложения,

ответ

10

У вас есть две проблемы в вашем коде, внутри вашего onMovieSelected метода:

  1. Вы создаете новый экземпляр из ListMovieFragment, а затем применить логику переходов к Это. Но вы забыли, что у вас уже есть экземпляр этого фрагмента (вы были созданы в методе onCreate). Итак, вам нужно получить существующий объект ListMovieFragment с FragmentManager и применить к нему свои переходы.
  2. Вы применяете переходную логику к одному экземпляру DetailMovieFragment, но затем внезапно заменяете ListMoveFragment на новый.

Таким образом, ваш фиксированный onMovieSelected метод будет:

@Override 
public void onMovieSelected(int movieId) { 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     /* Get the fragments that will be using the transition */ 
     ListMovieFragment listMovieFragment = (ListMovieFragment) getSupportFragmentManager().findFragmentByTag("listmoviefragment"); 
     DetailMovieFragment detailMovieFragment = new DetailMovieFragment(); 

     /* Inflate the transition */ 
     Transition changeTransition = TransitionInflater 
       .from(MainActivity.this) 
       .inflateTransition(R.transition.change_image_transform); 

     Transition explodeTransition = TransitionInflater 
       .from(MainActivity.this) 
       .inflateTransition(android.R.transition.explode); 

     /* Set the exit and return on the source fragment (ListMovieFragment) */ 
     listMovieFragment.setSharedElementReturnTransition(changeTransition); 
     listMovieFragment.setExitTransition(explodeTransition); 

     /* Set the enter on the destination fragment (MovieDetailFragment) */ 
     detailMovieFragment.setSharedElementEnterTransition(changeTransition); 
     detailMovieFragment.setEnterTransition(explodeTransition); 

     /* Get the shared imageview from the source fragment (MovieListFragment) */ 
     final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster); 

     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, "detailmoviefragment"); 
     fragmentTransaction.addToBackStack("detailmoviefragment"); 
     fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image)); 
     fragmentTransaction.commit(); 
    } else { 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment"); 
     fragmentTransaction.addToBackStack("detailmoviefragment"); 
     fragmentTransaction.commit(); 
    } 
} 

Теперь это должно работать.

P.S. Я использовал ваш код и запускал его, и заметил, что у вас есть некоторые странные переходы, поэтому, если у вас возникнут некоторые проблемы, проверьте это great article, как сделать плавные и удобные переходы с фрагментами :)

+0

Спасибо, что помогло. – ant2009

+0

Сделав все исправления. Переход выглядит великолепно, входя в detailFragment. Но когда кнопка «Назад» нажата, переход не переходит. Я думал, что это произошло автоматически, когда фрагмент выскочил из задней части. Это верно? – ant2009

+0

Да, вам, вероятно, необходимо добавить обратный переход к 'detailMovieFragment', например:' detailMovieFragment.setSharedElementReturnTransition (changeTransition); '. Полагаю, что это должно решить вашу проблему. – rom4ek

3

Don ' t создать новый объект Fragment при добавлении к транзакции фрагмента, повторно использовать существующий фрагмент, в который вы применили переход ввода и выхода.

 public class MainActivity extends AppCompatActivity implements ListMovieFragment.MovieSelectedListener { 

      @Override 
      protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.activity_main); 
       if(savedInstanceState == null) { 
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
         ListMovieFragment listMovieFragment = new ListMovieFragment(); 
         Transition changeTransition = TransitionInflater 
           .from(MainActivity.this) 
           .inflateTransition(R.transition.change_image_transform); 

         Transition explodeTransition = TransitionInflater 
           .from(MainActivity.this) 
           .inflateTransition(android.R.transition.explode); 
         listMovieFragment.setSharedElementReturnTransition(changeTransition); 
         listMovieFragment.setExitTransition(explodeTransition); 
         FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
         //don't create new ListMovieFragment use existing listMovieFragment instance 
         fragmentTransaction.add(R.id.activity_main, listMovieFragment, "listmoviefragment"); 
         fragmentTransaction.commit(); 
        }else { 
         FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
         fragmentTransaction.add(R.id.activity_main, new ListMovieFragment(), "listmoviefragment"); 
         fragmentTransaction.commit(); 
        } 
       } 
      } 

      @Override 
      public void onMovieSelected(int movieId) { 
       if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
        /* Get the fragments that will be using the transition */ 
        ListMovieFragment listMovieFragment = new ListMovieFragment(); 
        DetailMovieFragment detailMovieFragment = new DetailMovieFragment(); 

        /* Inflate the transition */ 
        Transition changeTransition = TransitionInflater 
          .from(MainActivity.this) 
          .inflateTransition(R.transition.change_image_transform); 

        Transition explodeTransition = TransitionInflater 
          .from(MainActivity.this) 
          .inflateTransition(android.R.transition.explode); 

        /* Set the exit and return on the source fragment (ListMovieFragment) */ 
        listMovieFragment.setSharedElementReturnTransition(changeTransition); 
        listMovieFragment.setExitTransition(explodeTransition); 

        /* Set the enter on the destination fragment (MovieDetailFragment) */ 
        detailMovieFragment.setSharedElementEnterTransition(changeTransition); 
        detailMovieFragment.setEnterTransition(explodeTransition); 

        /* Get the shared imageview from the source fragment (MovieListFragment) */ 
        final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster); 

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
        //don't create new DetailMovieFragment use existing detailMovieFragment instance 
        fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, "detailmoviefragment"); 
        fragmentTransaction.addToBackStack("detailmoviefragment"); 
        fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image)); 
        fragmentTransaction.commit(); 
       } 
       else { 
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
        fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment"); 
        fragmentTransaction.addToBackStack("detailmoviefragment"); 
        fragmentTransaction.commit(); 
       } 
      } 
      @Override 
      public void onBackPressed() { 
       if(getSupportFragmentManager().getBackStackEntryCount() > 0) { 
        getSupportFragmentManager().popBackStackImmediate(); 
       } 
       else { 
        super.onBackPressed(); 
       } 
      } 
     } 
+3

Спасибо, это помогло – ant2009

Смежные вопросы