studio programacion para libros gratis edición desarrollo desarrollar aprende aplicaciones android android-layout android-fragments android-dialogfragment

android - programacion - Transición de elemento compartido no funciona



programacion android pdf 2018 (3)

Antes de bucear en ...

Primero, destacemos algunos puntos sobre cómo el marco de Android hace la transición del elemento compartido mágico.

Una transición de elementos compartidos es solo una de las mentiras de Android Framework Cuando realiza una transición de elemento compartido, en realidad no está compartiendo ninguna vista entre sus actividades, ei, cada actividad tiene un árbol de vista independiente.

Supongamos que está intentando realizar la transición de un element identificado por element1 de Activity1 a element2 en Activity2 .

Lo que hace el marco es que busca cierta información como el tamaño ( width , height ) y la posición ( x , y ) de su elemento1 en la Activity1 . Luego pasa esta información a la Activity2 , aplíquela en el element2 y comienza la transición de la actividad al animar su element2 que crea esta ilusión del elemento que se comparte.

Sin embargo, esto requiere que se cree la Activity2 que se encuentre la view correspondiente al element2 antes de poder iniciar cualquier animación.

En el caso de usar un Fragment , llamar a FragmentTransaction.commit() solo programará su transacción de fragmento (el fragmento no se creará de inmediato), por lo que cuando se crea su element2 falta su element2 (como se explicó, eso se debe a que su fragmento que contiene no tiene). No se ha creado todavía).

Solución

Asegúrate de que tu element2 esté creado antes de que comience la animación. Por lo tanto, tendrá que encontrar una manera de decirle al marco que no haga lo habitual, pero en lugar de eso, espere su señal antes de crear la animación.

Una forma de hacerlo es alterar su código para que sea algo similar a este:

Actividad2

class Activity2 extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { // ... // Tell the framework to wait. postponeEnterTransition(); } }

Fragmento 2

class Fragment2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View element2 = getView().findViewById(R.id.element); sharedview.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // Tell the framework to start. sharedview.getViewTreeObserver().removeOnPreDrawListener(this); getActivity().startPostponedEnterTransition(); return true; } }); ... } }

Otras lecturas

Comenzando con la actividad y transiciones de fragmentos

He hecho un proyecto github con sólo el problema. Puede verlo / clonarlo / construirlo desde aquí: https://git.io/vMPqb

Estoy tratando de obtener elementos compartidos trabajando para una transición de Fragmento.

Hay dos FAB en el proyecto: Feather y Plane. La pluma y el plano son elementos compartidos. Cuando se hace clic en Feather, se abre el SheetDialog, y Feather debería animarse en el cuadro de diálogo Plano. No lo hace en este momento, y estoy tratando de determinar por qué.

Puede que valga la pena tener en cuenta que estoy ejecutando esto en la API 24, por lo que los problemas con las transiciones que no son compatibles con la versión 21 no son el problema.

¿Alguien puede decirme por qué las transiciones de elementos compartidos no funcionan?

Para hacer eco de lo que hay en el repositorio, hay cuatro archivos importantes:

Actividad principal

package test.example.fabpop; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.transition.ChangeBounds; import android.support.transition.Fade; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { FloatingActionButton fab_feather; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fab_feather = (FloatingActionButton) findViewById(R.id.initial_fab_feather); } public void fabClick(View view) { SheetDialog dialogFragment = new SheetDialog(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // This seemingly has no effect. I am trying to get it to work. transaction.addSharedElement(fab_feather, "transition_name_plane"); dialogFragment.setSharedElementEnterTransition(new ChangeBounds()); dialogFragment.setSharedElementReturnTransition(new Fade(Fade.OUT)); dialogFragment.show(transaction, "frag_tag"); } }

activity_main.xml Layout

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="test.example.fabpop.MainActivity"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:orientation="vertical"> <TextView android:layout_width="200dp" android:layout_height="wrap_content" android:text="Transition to a BottomSheetDialogFragment that shares this FAB" android:textAlignment="center"/> <!-- Feather FAB --> <android.support.design.widget.FloatingActionButton android:id="@+id/initial_fab_feather" android:layout_width="52dp" android:layout_height="52dp" android:layout_margin="16dp" android:layout_gravity="center" android:onClick="fabClick" android:transitionName="transition_name_feather" android:src="@drawable/ic_feather" /> </LinearLayout> </RelativeLayout>

SheetDialog

package test.example.fabpop; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetDialogFragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class SheetDialog extends BottomSheetDialogFragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.dialog_sheet, container, false); } }

dialog_sheet.xml Layout

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Plane FAB --> <android.support.design.widget.FloatingActionButton android:id="@+id/final_fab_plane" android:layout_width="75dp" android:layout_height="75dp" android:layout_margin="16dp" android:transitionName="transition_name_plane" android:src="@drawable/ic_plane" /> </LinearLayout>

¿No es posible tener un elemento compartido en una transición entre una Actividad y un Fragmento? ¿Quizás solo es posible entre Actividad a Actividad o Fragmento a Fragmento, pero no a través de los dos tipos? Tal vez es por eso que no puedo hacerlo funcionar?

Actualizar:

Ahora he intentado agregar <item name="android:windowContentTransitions">true</item> al <item name="android:windowContentTransitions">true</item> de la aplicación.

También he intentado ahora asegurándome de que los dos valores de transición son iguales en ambas vistas.

Ninguno de estos ha ayudado a solucionar el problema.


Lo que estás buscando es este ejemplo: https://github.com/hujiaweibujidao/FabDialogMorph . Tenga en cuenta que lo que está tratando de lograr no es una transición estándar de Android, debe crear su propia transición de transformación basada en la transición de ChangeBounds . Originalmente, se ha mostrado en Plaid , gracias a Nick Butcher por eso, por lo que puede consultar más consejos y antecedentes.


Sólo citando los documentos de Android :

Iniciar una actividad con un elemento compartido.

  1. Asigne un nombre común a los elementos compartidos en ambos diseños con el atributo android: transitionName.

Por lo que veo, ambos XML no comparten el mismo android: transitionName .

Intente cambiar ambos android: transitionName en el diseño XML (activity_main.xml & dialog_sheet.xml) a una misma cadena, por ejemplo: transition_plane_feather

Yo mismo no he probado los códigos, pero creo que ese podría ser un buen punto de partida.

Consejo de bonificación

Si planea implementar completamente el Diseño de materiales sin compatibilidad con niveles de API más bajos (antes de Lollipop), le recomiendo que consulte una muestra realizada por un diseñador de UI / UX de Google: Plaid

Además, vea el excelente video complementario de YouTube para esa muestra: https://www.youtube.com/watch?v=EjTJIDKT72M

Le muestra algunos de los mejores trucos y prácticas que puede utilizar para implementar completamente el Diseño de materiales, así como las transiciones de elementos compartidos.