studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android fragment material-design

android - programacion - ¿Cómo comenzar la transición de elementos compartidos usando Fragments?



manual de programacion android pdf (7)

Busqué SharedElement en fragmentos y encuentro un código fuente muy útil en GitHub.

1.primero debe definir el nombre de transición para sus objetos (como ImageView) en ambos diseños de Fragmentos (agregamos un botón en el fragmento A para manejar el evento de clic):

fragmento A :

<ImageView android:id="@+id/fragment_a_imageView" android:layout_width="128dp" android:layout_height="96dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="80dp" android:scaleType="centerCrop" android:src="@drawable/gorilla" android:transitionName="@string/simple_fragment_transition /> <Button android:id="@+id/fragment_a_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="24dp" android:text="@string/gorilla" />

fragmento B:

<ImageView android:id="@+id/fragment_b_image" android:layout_width="match_parent" android:layout_height="250dp" android:scaleType="centerCrop" android:src="@drawable/gorilla" android:transitionName="@string/simple_fragment_transition" />

  1. Luego, debe escribir este código en su archivo de transición en el Directorio de transición (si no tiene este Directorio, cree One: res> new> Android Resource Directory> Resource Type = transition> name = change_image_transform):

change_image_transform.xml:

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

  1. En el último paso, debe completar los códigos en Java:

fragmento A:

public class FragmentA extends Fragment { public static final String TAG = FragmentA.class.getSimpleName(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_a, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); final ImageView imageView = (ImageView) view.findViewById(R.id.fragment_a_imageView); Button button = (Button) view.findViewById(R.id.fragment_a_btn); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { getFragmentManager() .beginTransaction() .addSharedElement(imageView, ViewCompat.getTransitionName(imageView)) .addToBackStack(TAG) .replace(R.id.content, new FragmentB()) .commit(); } }); } }

fragmento B:

public class FragmentB extends Fragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move)); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_b, container, false); } }

no olvides mostrar tu fragmento "A" en tu actividad:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportFragmentManager() .beginTransaction() .add(R.id.content, new SimpleFragmentA()) .commit(); }

fuente: https://github.com/mikescamell/shared-element-transitions

Estoy tratando de implementar transiciones entre fragmentos que tienen "elementos compartidos" como se describe en las nuevas especificaciones de diseño de materiales. El único método que puedo encontrar es ActivityOptionsCompat.makeSceneTransitionAnimation , que creo que funciona solo en Activity. He estado buscando esta misma funcionalidad pero con / para fragmentos.


Esto debería ser un comentario a la respuesta aceptada, ya que no puedo hacer ningún comentario al respecto.

La respuesta aceptada (por WindsurferOak y ar34z) funciona, excepto por un problema "menor" que causó una excepción de puntero nulo al navegar con BackStack. Parece que se debe llamar a setSharedElementReturnTransition() en el fragmento de destino en lugar del fragmento original.

Entonces en lugar de:

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

debería ser

fragment.setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));

https://github.com/tevjef/Rutgers-Course-Tracker/issues/8


Estoy publicando esto como respuesta, ya que soy nuevo aquí y no puedo comentar.

Las transiciones de fragmentos de elementos compartidos funcionan con ListViews, siempre que las vistas de origen y destino tengan el mismo (y único) nombre de transición.

Si hace que su adaptador de vista de lista establezca nombres de transición únicos para las vistas que desea (por ejemplo, alguna identificación de elemento constante + específica) y también cambie su fragmento de detalle para establecer los mismos nombres de transición a las vistas de destino en tiempo de ejecución (onCreateView), las transiciones realmente funcionan !


La clave es usar una transacción personalizada con

transaction.addSharedElement(sharedElement, "sharedImage");

Transición de elementos compartidos entre dos fragmentos

En este ejemplo, uno de los dos ImageViews diferentes se debe traducir del ChooserFragment al DetailFragment .

En el diseño ChooserFragment necesitamos los atributos únicos de nombre de transitionName :

<ImageView android:id="@+id/image_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_first" android:transitionName="fistImage" /> <ImageView android:id="@+id/image_second" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_second" android:transitionName="secondImage" />

En la clase ChooserFragments , necesitamos pasar la View que se hizo clic y una ID a la Activity principal que maneja el reemplazo de los fragmentos (necesitamos la ID para saber qué recurso de imagen mostrar en el DetailFragment ). Cómo pasar información a la actividad de un padre en detalle seguramente está cubierto en otra documentación.

view.findViewById(R.id.image_first).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mCallback != null) { mCallback.showDetailFragment(view, 1); } } }); view.findViewById(R.id.image_second).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mCallback != null) { mCallback.showDetailFragment(view, 2); } } });

En DetailFragment , ImageView del elemento compartido también necesita el atributo de transitionName único.

<ImageView android:id="@+id/image_shared" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:transitionName="sharedImage" />

En el método onCreateView() del DetailFragment , tenemos que decidir qué recurso de imagen se debe mostrar (si no lo hacemos, el elemento compartido desaparecerá después de la transición).

public static DetailFragment newInstance(Bundle args) { DetailFragment fragment = new DetailFragment(); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.fragment_detail, container, false); ImageView sharedImage = (ImageView) view.findViewById(R.id.image_shared); // Check which resource should be shown. int type = getArguments().getInt("type"); // Show image based on the type. switch (type) { case 1: sharedImage.setBackgroundResource(R.drawable.ic_first); break; case 2: sharedImage.setBackgroundResource(R.drawable.ic_second); break; } return view; }

La Activity principal está recibiendo las devoluciones de llamada y maneja el reemplazo de los fragmentos.

@Override public void showDetailFragment(View sharedElement, int type) { // Get the chooser fragment, which is shown in the moment. Fragment chooserFragment = getFragmentManager().findFragmentById(R.id.fragment_container); // Set up the DetailFragment and put the type as argument. Bundle args = new Bundle(); args.putInt("type", type); Fragment fragment = DetailFragment.newInstance(args); // Set up the transaction. FragmentTransaction transaction = getFragmentManager().beginTransaction(); // Define the shared element transition. fragment.setSharedElementEnterTransition(new DetailsTransition()); fragment.setSharedElementReturnTransition(new DetailsTransition()); // The rest of the views are just fading in/out. fragment.setEnterTransition(new Fade()); chooserFragment.setExitTransition(new Fade()); // Now use the image''s view and the target transitionName to define the shared element. transaction.addSharedElement(sharedElement, "sharedImage"); // Replace the fragment. transaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName()); // Enable back navigation with shared element transitions. transaction.addToBackStack(fragment.getClass().getSimpleName()); // Finally press play. transaction.commit(); }

Sin olvidar: la Transition sí. Este ejemplo mueve y escala el elemento compartido.

@TargetApi(Build.VERSION_CODES.LOLLIPOP) public class DetailsTransition extends TransitionSet { public DetailsTransition() { setOrdering(ORDERING_TOGETHER); addTransition(new ChangeBounds()). addTransition(new ChangeTransform()). addTransition(new ChangeImageTransform()); } }


Los elementos compartidos funcionan con Fragmentos, pero hay algunas cosas a tener en cuenta:

  1. No intente configurar sharedElementsTransition en onCreateView de su Fragment. onCreate definirlos al crear una instancia de su Fragmento o en onCreate .

  2. Tome nota de la documentación oficial sobre las posibles animaciones para las transiciones de entrada / salida y sharedElementTransition. Ellos no son los mismos.

  3. Prueba y error :)



Tuve el mismo problema pero lo hice funcionar agregando un nuevo fragmento de otro fragmento. El siguiente enlace es muy útil para comenzar con esto: https://developer.android.com/training/material/animations.html#Transitions

El siguiente es mi código que funciona. Estoy animando un ImageView de un fragmento a otro. Asegúrese de que la View que desea animar tenga el mismo android:transitionName en ambos fragmentos. El otro contenido realmente no importa.

Como prueba, puede copiar esto en sus archivos xml de diseño. Asegúrate de que la imagen exista.

<ImageView android:transitionName="MyTransition" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/test_image" />

Luego tengo 1 archivo en mi carpeta res/transition , llamado change_image_transform.xml .

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

Ahora puedes comenzar. Digamos que tiene el Fragmento A que contiene la imagen y desea agregar el Fragmento B.

Ejecute esto en el Fragmento A:

@Override public void onClick(View v) { switch(v.getId()) { case R.id.product_detail_image_click_area: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform)); setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode)); // Create new fragment to add (Fragment B) Fragment fragment = new ImageFragment(); fragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform)); fragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode)); // Our shared element (in Fragment A) mProductImage = (ImageView) mLayout.findViewById(R.id.product_detail_image); // Add Fragment B FragmentTransaction ft = getFragmentManager().beginTransaction() .replace(R.id.container, fragment) .addToBackStack("transaction") .addSharedElement(mProductImage, "MyTransition"); ft.commit(); } else { // Code to run on older devices } break; } }