¿Qué API se utilizan para dibujar sobre otras aplicaciones (como los Chat Heads de Facebook)?

226

¿Cómo crea Facebook los Chat Heads en Android? ¿Cuál es la API para crear las vistas flotantes sobre todas las demás vistas?

Daniel A. White
fuente
66
Esta aplicación también tiene "Chat Heads" play.google.com/store/apps/details?id=com.ninja.sms
Oli
11
Si está buscando un ejemplo, visite github.com/marshallino16/FloatingNotification
marshallino16 el
55
Puede encontrar una demostración y una biblioteca simple aquí: github.com/ericbhatti/floaties Con esta biblioteca puede crear ventanas flotantes con solo 2 líneas.
Eric B.

Respuestas:

217

Este :

Permite que una aplicación abra ventanas usando el tipo TYPE_SYSTEM_ALERT, que se muestra en la parte superior de todas las demás aplicaciones. Muy pocas aplicaciones deberían usar este permiso; Estas ventanas están destinadas a la interacción a nivel de sistema con el usuario.

Valor constante: "android.permission.SYSTEM_ALERT_WINDOW"

// EDITAR: el código completo aquí :

public class ChatHeadService extends Service {

  private WindowManager windowManager;
  private ImageView chatHead;

  @Override public IBinder onBind(Intent intent) {
    // Not used
    return null;
  }

  @Override public void onCreate() {
    super.onCreate();

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.android_head);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_PHONE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;

    windowManager.addView(chatHead, params);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (chatHead != null) windowManager.removeView(chatHead);
  }
}

No olvide iniciar el servicio de alguna manera:

startService(new Intent(context, ChatHeadService.class));

.. Y agregue este servicio a su Manifiesto.

Waza_Be
fuente
44
Hay más cosas raras, creo. ¿Qué pasa con el manejo de entrada fuera de la "cabeza", así como la dragabilidad? Creo que al menos necesitará FLAG_NOT_TOUCH_MODAL , así como también una lógica inteligente para actualizar los atributos de la Ventana (es decir, moverla) mientras la arrastra.
Delyan
2
en que cómo eliminar chat -heads?
Nirav Mehta
66
Pensé que vale la pena mencionar un SDK que desarrollé para crear una interfaz de usuario flotante: www.tooleap.com
Arik
@NiravMehta ¿Puedes eliminar las cabezas de chat?
KK_07k11A0585
cómo eliminar el margen de la cabeza del chat. Debido a que en el código de salida anterior el círculo tiene algo de espacio desde el borde. En Facebook la burbuja no tiene ese espacio
Depurador
51

Como regla general, las actividades de Android son UI de pantalla completa, conceptualmente dedicadas que toman toda la interacción. Hay algunas excepciones a esto. Para empezar, hay cuadros de diálogo emergentes que no llenan la pantalla. Otro es el brindis de Android, que es una ventana emergente no interactiva: no puede tocarlo y, si lo intenta, irá a lo que esté debajo.

También puedes hacer tus propias IU especiales. Puede agregar vistas directamente al WindowManager, especificando un indicador de tipo. Chat Heads probablemente usa TYPE_PHONE . Hay algunos tipos similares, pero el propósito es el mismo: superposiciones de propósito especial que pueden aparecer sobre la parte superior de cualquier otra cosa sin que la aplicación principal aparentemente esté presente.

Sin embargo, eso solo te lleva muy lejos, debido a problemas de interacción. Al principio, su superposición absorberá toda la interacción, por lo que no solo la cabeza recibe eventos, sino que bloquea la interacción con todo lo que está debajo.

Configura este comportamiento utilizando los LayoutParams . FLAG_NOT_TOUCH_MODALsignifica que los eventos fuera de su área de visualización van a las IU subyacentes. Ahora descubrirá que funciona, pero que otras cosas malas aún suceden, como los botones de retroceso / menú no se dirigen a las aplicaciones, además de que no hay teclado. Para resolver eso que necesitas FLAG_NOT_FOCUSABLE.

También obtiene un efecto secundario del bit no enfocable, que ya no es una buena interacción con su superposición, por ejemplo, al presionar botones. Sin embargo, puede obtener algunos eventos táctiles básicos, en los que siempre puede hacer cálculos, y eso probablemente sea suficiente para Chat Heads. Solo tenga en cuenta que lo deja solo en muchas áreas, como la animación de la interfaz de usuario.

Una buena visión general de los detalles, incluyendo el permitir para el consumo interacción selectiva, se puede encontrar en este hilo StackOverflow . En particular, uno de los enlaces de respuesta te llevará eventualmente aquí , lo cual es un buen proyecto de ejemplo. Tenga en cuenta que ICS cambió un poco la forma en que esto funciona, pero los hilos lo explican.

Todo esto es material público de API, pero en realidad no parece una cosa convencional que uno debería estar haciendo de forma natural. La documentación está llena de referencias a comportamientos especiales de la aplicación del sistema, y ​​con buenas razones; ¿Y si todos lo hicieran?

Rob Pridham
fuente
¿Podría bloquear de alguna manera los cambios de orientación para estas vistas? Si la actividad subyacente cambia de orientación, mi opinión también cambia su orientación.
MG
1
No. El cambio de orientación abarca todo el dispositivo, no solo para la actividad.
Rob Pridham
7

Springy heads ofrece un comportamiento basado en la primavera de los chat heads fuera de la caja. Todo lo que tiene que definir es el dibujo del encabezado del chat y el fragmento que se abrirá una vez que se haga clic en el encabezado del chat. Las cabezas de chat colapsan cuando se minimizan y siguen el dedo cuando se arrastran.

El proyecto incluye una aplicación de demostración que muestra todas las funciones integradas. Para usarlo, debe agregar esto a sus dependencias de gradle.

compile 'com.flipkart.springyheads:library:0.9.6'
Kiran Kumar
fuente
Hola @KiranKumar, has creado una biblioteca muy clara ... Me encanta ... Estoy tratando de aprender varios aspectos de esta biblioteca ... He estado tratando de ejecutarla fuera de la ventana de la aplicación, de alguna manera tengo un poco de éxito eso es así ... Pero, el problema surge cuando hago clic en el encabezado del chat fuera de la ventana de la aplicación ... el fragmento no podría abrir y devolver java.lang.OutOfMemoryError ... si pudiera ser posible de su lado para dame un poco de esto ... será un honor para
@arraystack ahora puedes ejecutarlo en un servicio. Verifique la lista si las sucursales en el repositorio de GitHub
Kiran Kumar
@KiranKumar Gracias, el problema con la nueva lib es el permiso de Draw over application en Marshmallow Version
arraystack