tutorial studio from fragments crear con como bottom aplicación activity android android-fragments navigation-drawer fragmenttransaction drawerlayout

android - studio - Elemento de DrawerLayout: ¿Cuándo es el momento adecuado para reemplazar el fragmento?



navigation drawer con fragments android studio (7)

Estoy desarrollando una aplicación que usa el patrón del cajón de navegación (con DrawerLayout).

Cada clic en un elemento de un cajón, reemplaza el fragmento en el contenedor principal.

Sin embargo, no estoy seguro de cuándo es el momento adecuado para hacer la transacción de fragmento? Cuando el cajón comienza a cerrarse? O después de que está cerrado?

En el ejemplo de documentación de Google, puede ver que están haciendo la transacción justo después de hacer clic en el elemento, y luego cerrar el cajón.
Como resultado, el cajón parece descuidado y no liso, y se ve muy mal (también sucede en mi aplicación).

En las aplicaciones de Gmail y Google Drive , por otro lado, parece que están haciendo la transacción después de cerrar el cajón (¿Estoy en lo cierto?).
Como resultado, el cajón no está descuidado y es muy suave, PERO se tarda aproximadamente 1 segundo (el tiempo que tarda en cerrarse el cajón) al menos, para ver el siguiente fragmento.

Parece que no hay forma de que el cajón se suavice al realizar inmediatamente una transacción de fragmento.

¿Qué piensas sobre eso?

¡Gracias por adelantado!


En lugar de retrasar los clics de tu artículo, puede hacer que tu aplicación se sienta lenta. Me gustaría retrasar el cierre de mDrawerLayout. No usaría DrawerLayout.OnDrawerListener onClose(...) ya sea porque esas devoluciones de llamadas tardan tanto en llamarse.

new Handler().postDelayed(new Runnable() { @Override public void run() { mDrawerLayout.closeDrawer(GravityCompat.START); } }, 200);


Esto es lo que hago para lograr una animación de transacción sin problemas similar a la aplicación de Gmail:

activity_drawer.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- The main content view --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="280dp" android:layout_height="match_parent" android:layout_gravity="left" android:choiceMode="singleChoice" /> </android.support.v4.widget.DrawerLayout>

DrawerActivity.java

private Fragment mContentFragment; private Fragment mNextContentFragment; private boolean mChangeContentFragment = false; private Handler mHandler = new Handler(); ... @Override public void onCreate(Bundle savedInstanceState) { ... mDrawerLayout.setDrawerListener(new DrawerListener()); mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); ... } .... private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { getSupportFragmentManager().beginTransaction().remove(mContentFragment).commit(); switch (position) { case 0: mNextContentFragment = new Fragment1(); break; case 1: mNextContentFragment = new Fragment2(); break; case 2: mNextContentFragment = new Fragment3(); break; } mChangeContentFragment = true; mDrawerList.setItemChecked(position, true); mHandler.postDelayed(new Runnable() { @Override public void run() { mDrawerLayout.closeDrawer(mDrawerList); } }, 150); } } private class DrawerListener implements android.support.v4.widget.DrawerLayout.DrawerListener { @Override public void onDrawerClosed(View view) { if (mChangeContentFragment) { getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).replace(R.id.content_frame, mNextContentFragment).commit(); mContentFragment = mNextContentFragment; mNextContentFragment = null; mChangeContentFragment = false; } } }

Espero que te ayude! :-)


Otra solución es crear un Handler y publicar un Runnable demorado después de cerrar el cajón, como se muestra aquí: https://.com/a/18483633/769501 . El beneficio de este enfoque es que sus fragmentos serán reemplazados mucho antes de lo que serían si esperara DrawerListener#onDrawerClosed() , pero por supuesto el retraso arbitrario no garantiza al 100% que la animación del cajón finalizará a tiempo.

Dicho esto, utilizo un retraso de 200 ms y funciona maravillosamente.

private class DrawerItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) { drawerLayout.closeDrawer(drawerList); new Handler().postDelayed(new Runnable() { @Override public void run() { switchFragments(position); // your fragment transactions go here } }, 200); } }


Sé que esta pregunta es antigua, pero me encontré con el mismo problema y pensé que publicaría mi solución, ya que creo que es una mejor implementación que agregar un tiempo de retardo codificado. Lo que hice fue usar la función onDrawerClosed para verificar que el cajón onDrawerClosed cerrado antes de realizar mi tarea.

//on button click... private void displayView(int position) { switch (position) { //if item 1 is selected, update a global variable `"int itemPosition"` to be 1 case 1: itemPosition = 1; //(); break; default: break; } // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true); mDrawerList.setSelection(position); mDrawerLayout.closeDrawer(mDrawerList); //close drawer }

y luego en onDrawerClosed , abra la actividad correspondiente.

public void onDrawerClosed(View view) { getSupportActionBar().setTitle(mTitle); // calling onPrepareOptionsMenu() to show action bar icons supportInvalidateOptionsMenu(); if (itemPosition == 1) { Intent intent = new Intent(BaseActivity.this, SecondActivity.class); startActivity(intent); } }


Sí, no podría estar más de acuerdo, la realización de un fragmento (con vista) de la transacción da como resultado un pase de diseño que causa animaciones janky en vistas animadas, citando developer.android.com/reference/android/support/v4/widget/… DrawerLayout :

DrawerLayout.DrawerListener se puede usar para controlar el estado y el movimiento de las vistas del cajón. Evite realizar operaciones costosas, como el diseño durante la animación, ya que puede causar tartamudez; intente realizar operaciones costosas durante el estado STATE_IDLE.

Por lo tanto, realice las transacciones de su fragmento una vez que el cajón esté cerrado o alguien revise la biblioteca de soporte para arreglarlo de alguna manera :)


Si lo quiere sin problemas y sin demora, deje el cajón abierto y ciérrelo al volver (en el método onRestart ()).

@Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); mDrawerLayout.closeDrawer(mDrawerList); }

El efecto secundario es una animación (rápida) al regresar, pero esto podría ser aceptable.


Simplemente escriba su código en un controlador y ponga 200 ms de retraso.

new Handler().postDelayed(new Runnable() { @Override public void run() { openSelectionDrawerItem(position); } }, 200);