5
AndroidStudio 2.3 Beta 1 

Ich versuche, Übergänge Arbeit mit Fragmenten zu bekommen, wie das Bild, das ich verwende, nicht übergeht. Es erscheint nur als normal.sharedElment Übergang mit Fragmenten nicht übergang

Ich habe eine einfache App erstellt, um zu versuchen, dies zur Arbeit zu bringen. Ich habe 2 Fragmente ListMovieFragment und DetailMovieFragment. Und 1 MainActivity. Der Benutzer wird auf das Bild in ListMovieFragment klicken, um zu DetailMovieFragment überzugehen.

Das ist mein Transition 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(); 
     } 
    } 
} 

Das Layout für 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> 

Layout für die 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> 

Der String Name für den Übergang Name:

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

Die Umsetzung scheint einfach so denke ich, mein Fehler ist etwas, das ich übersehe.

Vielen Dank für Ihre Anregungen,

Antwort

10

Sie haben zwei Probleme im Code, in Ihrer onMovieSelected Methode:

  1. Sie erstellen eine neue Instanz von ListMovieFragment und dann Übergang Logik gilt es. Aber Sie haben vergessen, dass Sie bereits die Instanz dieses Fragments haben (Sie wurden in onCreate Methode erstellt). Sie müssen also das vorhandene Objekt ListMovieFragment von FragmentManager abrufen und Ihre Übergänge darauf anwenden.
  2. Sie wenden Übergangslogik auf eine Instanz von DetailMovieFragment an, ersetzen dann aber plötzlich die ListMoveFragment durch die neue.

So Ihre Fest onMovieSelected Methode wird sein:

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

Jetzt sollte diese Arbeit.

P.S. Ich habe den Code und führen Sie es verwendet, und bemerkt haben Sie einige seltsame Übergänge, also wenn Sie einige Probleme haben, diese great article überprüfen, wie glatt und benutzerfreundliche Übergänge mit Fragmenten machen :)

+0

Danke dies als geholfen. – ant2009

+0

Nachdem alle Korrekturen vorgenommen wurden. Der Übergang sieht gut aus, indem du das detailFragment eingibst. Wenn Sie jedoch die Zurück-Taste drücken, wird der Übergang nicht umgeschaltet. Ich dachte, dass dies automatisch passiert, wenn Fragmente aus dem Backstack entnommen werden. Ist das richtig? – ant2009

+0

Ja, wahrscheinlich müssen Sie den Rückkehrübergang zu 'detailMovieFragment' hinzufügen, wie folgt:' detailMovieFragment.setSharedElementReturnTransition (changeTransition); '. Raten Sie, es sollte Ihr Problem lösen. – rom4ek

3

Don‘ t neues Objekt erstellen Fragment fügen beim Hinzufügen zur Fragmenttransaktion das vorhandene Fragment wieder ein, in dem Sie die Übergänge Enter und Exit angewendet haben.

 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

Danke das hat geholfen – ant2009