¿Hay alguna forma de hacer Snackbar persisten entre los cambios de actividad?

Aunque Snackbar es hermoso, no persiste al cambiar actividades. Esto es una lástima en los escenarios donde me gustaría confirmar que un mensaje fue enviado usando una Snackbar , antes de terminar la actividad. He considerado pausar el código antes de salir de la actividad, pero he encontrado que para ser una mala práctica.

Si lo que describo no es posible, ¿hay algún tipo de material de mensaje de brindis de diseño? O una manera de hacer un mensaje de tostada rectangular; Uno con bordes redondeados de un radio más pequeño?

Para crear una Snackbar con el contexto de la aplicación que es visible en varias actividades:

  1. Obtener el WindowManager como servicio del sistema
  2. Cree y agregue un FrameLayout ( rootView ) con el tipo WindowManager.LayoutParams.TYPE_TOAST y WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL al WindowManager
  3. Espere hasta que FrameLayout.onAttachedToWindow() se llame en FrameLayout ( rootView )
  4. Obtener el token de ventana de FrameLayout ( rootView ) con View.getWindowToken()
  5. Crear un ContextThemeWrapper con el contexto de la aplicación y un derivado @style/Theme.AppCompat
  6. Utilice el nuevo contexto para crear un FrameLayout adicional ( snackbarContainer )
  7. Agregue este FrameLayout ( snackbarContainer ) con el tipo WindowManager.LayoutParams.TYPE_APPLICATION_PANEL y flag WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
  8. Espere hasta que View.onAttachedToWindow() se llame en el FrameLayout ( snackbarContainer )
  9. Cree la Snackbar como de costumbre con FrameLayout ( snackbarContainer )
  10. Establezca la devolución de llamada View.onDismissed() a la Snackbar y elimine FrameLayouts ( rootView y snackbarContainer )
  11. Mostrar el snackbar Snackbar.show()

Aquí hay un wrapper de trabajo ( NOTA: Deslizar para descartar no funciona, quizás alguien más encuentre los indicadores correctos de WindowManager.LayoutParams para recibir eventos táctiles Fijo por CoordinatorLayout):

 public class SnackbarWrapper { private final CharSequence text; private final int duration; private final WindowManager windowManager; private final Context appplicationContext; @Nullable private Snackbar.Callback externalCallback; @Nullable private Action action; @NonNull public static SnackbarWrapper make(@NonNull Context applicationContext, @NonNull CharSequence text, @Snackbar.Duration int duration) { return new SnackbarWrapper(applicationContext, text, duration); } private SnackbarWrapper(@NonNull final Context appplicationContext, @NonNull CharSequence text, @Snackbar.Duration int duration) { this.appplicationContext = appplicationContext; this.windowManager = (WindowManager) appplicationContext.getSystemService(Context.WINDOW_SERVICE); this.text = text; this.duration = duration; } public void show() { WindowManager.LayoutParams layoutParams = createDefaultLayoutParams(WindowManager.LayoutParams.TYPE_TOAST, null); windowManager.addView(new FrameLayout(appplicationContext) { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); onRootViewAvailable(this); } }, layoutParams); } private void onRootViewAvailable(final FrameLayout rootView) { final CoordinatorLayout snackbarContainer = new CoordinatorLayout(new ContextThemeWrapper(appplicationContext, R.style.FOL_Theme_SnackbarWrapper)) { @Override public void onAttachedToWindow() { super.onAttachedToWindow(); onSnackbarContainerAttached(rootView, this); } }; windowManager.addView(snackbarContainer, createDefaultLayoutParams(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, rootView.getWindowToken())); } private void onSnackbarContainerAttached(final View rootView, final CoordinatorLayout snackbarContainer) { Snackbar snackbar = Snackbar.make(snackbarContainer, text, duration); snackbar.setCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { super.onDismissed(snackbar, event); // Clean up (NOTE! This callback can be called multiple times) if (snackbarContainer.getParent() != null && rootView.getParent() != null) { windowManager.removeView(snackbarContainer); windowManager.removeView(rootView); } if (externalCallback != null) { externalCallback.onDismissed(snackbar, event); } } @Override public void onShown(Snackbar snackbar) { super.onShown(snackbar); if (externalCallback != null) { externalCallback.onShown(snackbar); } } }); if (action != null) { snackbar.setAction(action.text, action.listener); } snackbar.show(); } private WindowManager.LayoutParams createDefaultLayoutParams(int type, @Nullable IBinder windowToken) { WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.gravity = GravityCompat.getAbsoluteGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, ViewCompat.LAYOUT_DIRECTION_LTR); layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; layoutParams.type = type; layoutParams.token = windowToken; return layoutParams; } @NonNull public SnackbarWrapper setCallback(@Nullable Snackbar.Callback callback) { this.externalCallback = callback; return this; } @NonNull public SnackbarWrapper setAction(CharSequence text, final View.OnClickListener listener) { action = new Action(text, listener); return this; } private static class Action { private final CharSequence text; private final View.OnClickListener listener; public Action(CharSequence text, View.OnClickListener listener) { this.text = text; this.listener = listener; } } } 

EDITAR
Una vez que SnackbarWrapper está definido, puedes usarlo así:

 final SnackbarWrapper snackbarWrapper = SnackbarWrapper.make(getApplicationContext(), "Test snackbarWrapper", Snackbar.LENGTH_LONG); snackbarWrapper.setAction(R.string.snackbar_text, new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "Action", Toast.LENGTH_SHORT).show(); } }); snackbarWrapper.show(); 

Si no tienes un tema, puedes definirlo rápidamente en styles.xml :

 <style name="FOL_Theme_SnackbarWrapper" parent="@style/Theme.AppCompat"> <!--Insert customization here--> </style> 

Si entiendo correctamente, usted hace esto:

  1. Actividad A iniciar Actividad B para enviar un mensaje
  2. Una vez enviado el mensaje, se muestra un mensaje de confirmación
  3. Regresa a la Actividad A

Puedes usar SnackBar para hacer eso usando un ActivityResult ( aquí hay un post StackOverflow con cómo usarlo)

Estos son los pasos:

  1. Actividad Actividad de lanzamiento B con startActivityForResult
  2. Haga sus cosas en la Actividad B
  3. Establezca el resultado (compruebe el vínculo anterior)
  4. Finalizar la actividad
  5. En la actividad A, obtenga ese código en OnActivityResult y muestre su SnackBar con el mensaje correcto

Esto le permite mostrar un Snackar en la Actividad A correspondiente al resultado de la Actividad B.

Esperanzas puede ayudar a su problema

Para tener un Toast rectangular, establezca un fondo rectangular para el Toast o simplemente establezca un color de fondo diferente para el Toast.

Refiera este mensaje donde fue publicado como un problema. Pero en su caso es una posible solución.

ACTUALIZACIÓN: Ver la respuesta seleccionada.

La mejor solución a mi pregunta es usar un Timer después de la presentación de la Snackbar y luego en el método run() del temporizador, iniciando la actividad.

 Snackbar.show(); // Excluded make for brevity. Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Intent chooseVideoIntent = new Intent(Intent.ACTION_GET_CONTENT); // Any type of content/file. Song, doc, video... chooseVideoIntent.setType("video/*"); startActivityForResult(chooseVideoIntent, CHOOSE_VIDEO_REQUEST); } }, 2 * 1000); 

UPDATE: Encontré que usando findViewById(android.R.id.content) como la vista en Snackbar.make() la findViewById(android.R.id.content) persiste entre los cambios de fragmento .

  • Cómo compilar la biblioteca de bifurcación en Gradle?
  • Gran número de errores durante la generación de Gradle después de actualizar a Android Studio 2.0
  • Configuración firebase en android
  • ¿Cómo ver todas las tareas de TODO en Android Studio?
  • Android Studio 0.2.9 y nuevo proyecto
  • MAVEN SDK no válido: Nivel de plataforma / API 16 no disponible
  • Error después de agregar dependencias a la barra de acción Sherlock en Android Studio 0.5.8
  • ¿Cómo habilitar la compilación externa en Android Studio permanentemente?
  • No se puede crear una aplicación cuando se usa gradle (Android Studio) y local maven repo
  • Cómo configurar la configuración de SONAR para el complemento de sonar intellij para Android Studio?
  • Android Studio: ejecuta la aplicación sin actividad de lanzador
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.