Welche APIs werden verwendet, um über andere Apps (wie die Chat Heads von Facebook) zu zeichnen?

226

Wie erstellt Facebook die Chat Heads auf Android? Was ist die API, um die schwebenden Ansichten über allen anderen Ansichten zu erstellen?

Daniel A. White
quelle
6
Diese App hat auch "Chat Heads" play.google.com/store/apps/details?id=com.ninja.sms
Oli
11
Wenn Sie nach einem Beispiel suchen, sehen Sie github.com/marshallino16/FloatingNotification
marshallino16
5
Eine Demo und eine einfache Bibliothek finden Sie hier: github.com/ericbhatti/floaties Mit dieser Bibliothek können Sie schwebende Fenster mit nur 2 Zeilen erstellen.
Eric B.

Antworten:

217

Dieser :

Ermöglicht einer Anwendung das Öffnen von Fenstern mit dem Typ TYPE_SYSTEM_ALERT, der über allen anderen Anwendungen angezeigt wird. Nur sehr wenige Anwendungen sollten diese Berechtigung verwenden. Diese Fenster sind für die Interaktion auf Systemebene mit dem Benutzer vorgesehen.

Konstanter Wert: "android.permission.SYSTEM_ALERT_WINDOW"

// EDIT: Den vollständigen Code hier :

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

Vergessen Sie nicht, den Dienst irgendwie zu starten:

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

.. Und fügen Sie diesen Service Ihrem Manifest hinzu.

Waza_Be
quelle
4
Es gibt noch mehr seltsame Sachen, denke ich. Was ist mit der Verarbeitung von Eingaben außerhalb des "Kopfes" sowie der Ziehbarkeit? Ich denke, Sie benötigen zumindest FLAG_NOT_TOUCH_MODAL sowie eine clevere Logik, um die Fensterattribute zu aktualisieren (dh zu verschieben), während Sie sie ziehen.
Delyan
2
wie man Chat-Köpfe entfernt?
Nirav Mehta
6
Ich dachte, es ist erwähnenswert, ein SDK zu erwähnen, das ich für die Erstellung einer schwebenden Benutzeroberfläche entwickelt habe: www.tooleap.com
Arik
@NiravMehta Können Sie die Chatköpfe entfernen?
KK_07k11A0585
So entfernen Sie den Rand des Chat-Kopfes. In der obigen Code-Ausgabe hat der Kreis etwas Platz vom Rand. In Facebook hat die Blase diesen Platz nicht
Debugger
51

Android-Aktivitäten sind in der Regel konzeptionell dedizierte Vollbild-Benutzeroberflächen, die die gesamte Interaktion übernehmen. Hiervon gibt es einige Ausnahmen. Zunächst gibt es Popup-Dialoge, die den Bildschirm nicht ausfüllen. Ein weiterer Grund ist der Android-Toast, bei dem es sich um ein nicht interaktives Popup handelt. Sie können ihn nicht berühren. Wenn Sie ihn ausprobieren, wird er zu dem angezeigt, was sich darunter befindet.

Sie können auch Ihre eigenen Benutzeroberflächen erstellen. Sie können Ansichten direkt zum hinzufügen WindowManagerund ein Typflag angeben. Chat Heads verwendet wahrscheinlich TYPE_PHONE . Es gibt einige ähnliche Typen, aber der Zweck ist der gleiche: Überlagerungen für spezielle Zwecke, die über allem anderen angezeigt werden können, ohne dass die übergeordnete Anwendung offensichtlich vorhanden ist.

Das bringt Sie jedoch nur aufgrund von Interaktionsproblemen so weit. Zuerst absorbiert Ihre Überlagerung die gesamte Interaktion, sodass der Kopf nicht nur Ereignisse erhält, sondern Sie die Interaktion für alles darunter blockieren.

Sie konfigurieren dieses Verhalten mit den LayoutParams . FLAG_NOT_TOUCH_MODALbedeutet, dass Ereignisse außerhalb Ihres Anzeigebereichs an die zugrunde liegenden Benutzeroberflächen gesendet werden. Sie werden jetzt feststellen, dass es funktioniert, aber dass andere schlimme Dinge immer noch passieren, wie die Schaltflächen Zurück / Menü, die nicht auf Apps gerichtet sind, und keine Tastatur. Um das zu lösen, brauchen Sie FLAG_NOT_FOCUSABLE.

Sie erhalten auch einen Nebeneffekt durch das nicht fokussierbare Bit, das keine netten Interaktionen mehr mit Ihrem Overlay darstellt, z. B. Drücken von Tasten. Sie können jedoch einige grundlegende Berührungsereignisse erhalten, an denen Sie immer rechnen können, und das ist wahrscheinlich genug für Chat Heads. Seien Sie sich nur bewusst, dass Sie in vielen Bereichen, wie z. B. der UI-Animation, allein sind.

Eine gute Übersicht über die Details, einschließlich der Berücksichtigung des selektiven Interaktionsverbrauchs, finden Sie in diesem StackOverflow-Thread . Insbesondere einer der Antwortlinks führt Sie irgendwann hierher , was ein gutes Beispielprojekt ist. Beachten Sie, dass ICS die Funktionsweise ein wenig geändert hat, aber die Threads erklären dies.

Dies ist alles öffentliches API-Zeug, aber es scheint nicht wirklich eine Mainstream-Sache zu sein, die man selbstverständlich tun sollte. Die Dokumentation ist mit Verweisen auf spezielle Verhaltensweisen von System-Apps übersät, und das aus gutem Grund. Was wäre, wenn alle es tun würden?

Rob Pridham
quelle
Könnte ich irgendwie Orientierungsänderungen für diese Ansicht blockieren? Wenn die zugrunde liegende Aktivität die Ausrichtung ändert, ändert meine Ansicht auch seine Ausrichtung.
MG
1
Nein. Die Orientierungsänderung ist geräteweit, nicht nur für die Aktivität.
Rob Pridham
7

Springy Heads bietet ein frühlingshaftes Verhalten von Chat-Köpfen. Sie müssen lediglich festlegen, dass der Chat-Kopf gezeichnet werden soll und das Fragment geöffnet werden soll, sobald auf den Chat-Kopf geklickt wird. Die Chatköpfe kollabieren beim Minimieren und folgen beim Ziehen dem Finger.

Das Projekt enthält eine Demo-App, die alle integrierten Funktionen demonstriert. Um es zu verwenden, müssen Sie dies zu Ihren Gradle-Abhängigkeiten hinzufügen.

compile 'com.flipkart.springyheads:library:0.9.6'
Kiran Kumar
quelle
Hey @KiranKumar, Sie haben eine sehr übersichtliche Bibliothek erstellt. Ich liebe es einfach. Ich versuche, verschiedene Aspekte aus dieser Bibliothek zu lernen. Ich habe versucht, sie außerhalb des Anwendungsfensters auszuführen. Irgendwie bin ich etwas erfolgreich darin das so .. Aber das Problem tritt auf, wenn ich auf den Chat-Kopf außerhalb des Fensters der App klicke .. das Fragment könnte java.lang.OutOfMemoryError nicht öffnen und zurückgeben .. wenn es von Ihrer Seite zu möglich wäre Geben Sie mir einen Weg durch diese .. Es wird gerne geehrt ..
Arraystack
@arraystack jetzt können Sie es in einem Dienst ausführen. Überprüfen Sie die Liste, wenn Zweige im GitHub-Repo
Kiran Kumar
@ KiranKumar Vielen Dank, das Problem mit der neuen Bibliothek ist die Erlaubnis von Draw over Anwendung in Marshmallow Version
Arraystack