Quelles API sont utilisées pour dessiner sur d'autres applications (comme les têtes de conversation de Facebook)?

226

Comment Facebook crée-t-il les têtes de conversation sur Android? Quelle est l'API pour créer les vues flottantes au-dessus de toutes les autres vues?

Daniel A. White
la source
6
Cette application a également des "têtes de chat" play.google.com/store/apps/details?id=com.ninja.sms
Oli
11
Si vous cherchez un exemple, consultez github.com/marshallino16/FloatingNotification
marshallino16
5
Vous pouvez trouver une démo et une bibliothèque simple ici: github.com/ericbhatti/floaties En utilisant cette bibliothèque, vous pouvez créer des fenêtres flottantes en utilisant seulement 2 lignes.
Eric B.

Réponses:

217

Celui- ci:

Permet à une application d'ouvrir des fenêtres en utilisant le type TYPE_SYSTEM_ALERT, affiché au-dessus de toutes les autres applications. Très peu d'applications devraient utiliser cette autorisation; ces fenêtres sont destinées à une interaction au niveau du système avec l'utilisateur.

Valeur constante: "android.permission.SYSTEM_ALERT_WINDOW"

// EDIT: Le code complet ici :

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);
  }
}

N'oubliez pas de démarrer le service d'une manière ou d'une autre:

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

.. Et ajoutez ce service à votre manifeste.

Waza_Be
la source
4
Il y a plus de trucs bizarres, je pense. Qu'en est-il de la gestion des entrées en dehors de la "tête" ainsi que de la capacité de glisser? Je pense que vous auriez au moins besoin de FLAG_NOT_TOUCH_MODAL , ainsi que d'une logique intelligente pour mettre à jour les attributs de la fenêtre (c'est-à-dire le déplacer) pendant que vous le faites glisser.
Delyan
2
en cela comment supprimer les têtes de chat?
Nirav Mehta
6
J'ai pensé qu'il valait la peine de mentionner un SDK que j'ai développé pour créer une interface utilisateur flottante: www.tooleap.com
Arik
@NiravMehta Pouvez-vous supprimer les têtes de chat?
KK_07k11A0585
comment supprimer la marge de la tête de conversation.Parce que dans le code ci-dessus, le cercle a un peu d'espace à partir de la frontière.Dans Facebook, la bulle n'a pas cet espace
Débogueur
51

En règle générale, les activités Android sont en plein écran, des interfaces utilisateur conceptuellement dédiées qui prennent toute l'interaction. Il y a quelques exceptions à cela. Pour commencer, il existe des boîtes de dialogue contextuelles qui ne remplissent pas l'écran. Un autre est le toast Android, qui est une fenêtre contextuelle non interactive - vous ne pouvez pas le toucher, et si vous essayez, il ira à tout ce qui se trouve en dessous.

Vous pouvez également créer vos propres interfaces utilisateur spéciales. Vous pouvez ajouter des vues directement à WindowManager, en spécifiant un indicateur de type. Les têtes de conversation utilisent probablement TYPE_PHONE . Il existe quelques types similaires, mais le but est le même: des superpositions à usage spécial qui peuvent apparaître par-dessus toute autre chose sans que l'application parent soit apparemment présente.

Cependant, cela ne vous amène à ce jour qu'en raison de problèmes d'interaction. Au début, votre superposition absorbera toute l'interaction, donc non seulement la tête reçoit des événements, mais vous bloquez l'interaction avec tout ce qui se trouve en dessous.

Vous configurez ce comportement à l'aide des LayoutParams . FLAG_NOT_TOUCH_MODALsignifie que les événements en dehors de votre zone d'affichage vont aux interfaces utilisateur sous-jacentes. Vous verrez maintenant que cela fonctionne, mais que d'autres mauvaises choses se produisent toujours, comme les boutons de retour / menu ne sont pas dirigés vers les applications, plus aucun clavier. Pour résoudre ce problème, vous en avez besoin FLAG_NOT_FOCUSABLE.

Vous obtenez également un effet secondaire du bit non focalisable, ce qui n'est plus une bonne interaction avec votre superposition, par exemple des pressions sur des boutons. Vous pouvez obtenir des événements tactiles de base, sur lesquels vous pouvez toujours faire des calculs, et c'est probablement suffisant pour les têtes de conversation. Sachez simplement que cela vous laisse seul dans de nombreux domaines, comme l'animation d'interface utilisateur.

Un bon aperçu des détails, y compris la possibilité d'une consommation d'interaction sélective, peut être trouvé dans ce thread StackOverflow . En particulier, l'un des liens de réponse vous mènera éventuellement ici , qui est un bon exemple de projet. Notez qu'ICS a un peu changé la façon dont cela fonctionne, mais les discussions expliquent cela.

Ce sont tous des trucs d'API publics, mais cela ne semble pas vraiment être une chose courante que l'on devrait faire, bien sûr. La documentation est jonchée de références à des comportements d'application système spéciaux, et pour cause; Et si tout le monde le faisait?

Rob Pridham
la source
Puis-je bloquer en quelque sorte les changements d'orientation pour ces vues? Si l'activité sous-jacente change d'orientation, ma vue change également son orientation.
MG
1
Non. Le changement d'orientation concerne l'ensemble de l'appareil, pas seulement pour l'activité.
Rob Pridham
7

Les têtes élastiques donnent un comportement basé sur les ressorts des têtes de chat hors de la boîte. Tout ce que vous avez à définir est le dessinable pour la tête de conversation et le fragment à ouvrir une fois que la tête de conversation est cliquée. Les têtes de discussion s'effondrent lorsqu'elles sont réduites et suivent le doigt lorsqu'elles sont déplacées.

Le projet comprend une application de démonstration qui montre toutes les fonctionnalités intégrées. Pour l'utiliser, vous devez l'ajouter à vos dépendances gradle.

compile 'com.flipkart.springyheads:library:0.9.6'
Kiran Kumar
la source
Hé @KiranKumar, vous avez créé une bibliothèque très claire .. J'adore ça .. J'essaie d'apprendre différents aspects de cette bibliothèque .. J'ai essayé de l'exécuter en dehors de la fenêtre de l'application, d'une manière ou d'une autre, je réussis légèrement à le faire que oui .. Mais, le problème se pose lorsque je clique sur la tête de discussion en dehors de la fenêtre de l'application .. le fragment ne pourrait pas s'ouvrir et renvoyer java.lang.OutOfMemoryError .. si cela pouvait être possible de votre côté à donnez-moi un moyen de traverser cela .. Ce sera un plaisir d'honorer ..
arraystack
@arraystack vous pouvez maintenant l'exécuter dans un service. Vérifiez la liste des succursales dans le dépôt GitHub
Kiran Kumar
@KiranKumar Merci, Le problème avec la nouvelle lib est la permission de Draw over application dans la version Marshmallow
arraystack