Quali API vengono utilizzate per disegnare su altre app (come le testate di chat di Facebook)?


226

In che modo Facebook crea i Head Chat su Android? Qual è l'API per creare le viste mobili sopra tutte le altre viste?


6
Questa app ha anche "Chat Heads" play.google.com/store/apps/details?id=com.ninja.sms
Oli

11
Se stai cercando un esempio, vedi github.com/marshallino16/FloatingNotification
marshallino16

5
Puoi trovare una demo e una semplice libreria qui: github.com/ericbhatti/floaties Usando questa libreria puoi creare finestre mobili usando solo 2 righe.
Eric B.

Risposte:


217

Questo :

Consente a un'applicazione di aprire Windows utilizzando il tipo TYPE_SYSTEM_ALERT, mostrato in cima a tutte le altre applicazioni. Pochissime applicazioni dovrebbero usare questa autorizzazione; queste finestre sono destinate all'interazione a livello di sistema con l'utente.

Valore costante: "android.permission.SYSTEM_ALERT_WINDOW"

// EDIT: il codice completo qui :

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

Non dimenticare di avviare il servizio in qualche modo:

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

.. E aggiungi questo servizio al tuo manifest.


4
Ci sono altre cose strane, penso. Che dire della gestione dell'input al di fuori della "testa" e della trascinabilità? Penso che avresti almeno bisogno di FLAG_NOT_TOUCH_MODAL , oltre a una logica intelligente per aggiornare gli attributi di Window (cioè spostarlo) mentre lo trascini.
Delyan,

2
in che modo rimuovere le testate di chat?
Nirav Mehta,

6
Ho pensato che valesse la pena menzionare un SDK che ho sviluppato per creare un'interfaccia utente mobile: www.tooleap.com
Arik

@NiravMehta Sei in grado di rimuovere le teste di chat?
KK_07k11A0585

come rimuovere il margine della testa della chat. Perché nel codice sopra riportato l'output del cerchio ha un po 'di spazio dal bordo. In Facebook la bolla non ha quello spazio
Debugger

51

Di norma, le attività Android sono UI a schermo intero e concettualmente dedicati che prendono tutte le interazioni. Ci sono alcune eccezioni a questo. Per cominciare, ci sono finestre di dialogo popup che non riempiono lo schermo. Un altro è il toast Android, che è un popup non interattivo: non puoi toccarlo e, se lo provi, andrà a tutto ciò che c'è sotto.

Puoi anche creare le tue UI speciali. È possibile aggiungere viste direttamente a WindowManager, specificando un flag di tipo. Chat Heads probabilmente utilizza TYPE_PHONE . Esistono alcuni tipi simili, ma lo scopo è lo stesso: sovrapposizioni di scopi speciali che possono apparire sopra ogni altra cosa senza che l'applicazione padre apparentemente sia presente.

Questo ti porta solo finora, a causa di problemi con l'interazione. All'inizio, il tuo overlay assorbirà tutta l'interazione, quindi non solo la testa riceve eventi, ma blocchi l'interazione con tutto ciò che c'è sotto.

Configurare questo comportamento utilizzando LayoutParams . FLAG_NOT_TOUCH_MODALsignifica che gli eventi al di fuori dell'area di visualizzazione vanno all'interfaccia utente sottostante. Ora scoprirai che funziona, ma che succedono altre cose brutte, come i pulsanti indietro / menu non vengono indirizzati alle app, oltre a nessuna tastiera. Per risolvere ciò di cui hai bisogno FLAG_NOT_FOCUSABLE.

Si ottiene anche un effetto collaterale dal bit non focalizzabile, che non è più una piacevole interazione con il proprio overlay, ad esempio la pressione dei pulsanti. Tuttavia, puoi ottenere alcuni eventi tattili di base, sui quali puoi sempre fare calcoli, e probabilmente è abbastanza per Chat Head. Basta essere consapevoli del fatto che ti lascia da solo in molte aree, come l'animazione dell'interfaccia utente.

In questa discussione StackOverflow è disponibile una buona panoramica dei dettagli, incluso il consumo selettivo dell'interazione . In particolare uno dei link di risposta alla fine ti porterà qui , che è un buon progetto di esempio. Nota che ICS ha cambiato il modo in cui funziona un po ', ma i thread lo spiegano.

Questa è tutta roba API pubblica, ma in realtà non sembra una cosa tradizionale che si dovrebbe fare come una cosa ovvia. La documentazione è piena di riferimenti a comportamenti speciali delle app di sistema e con buone ragioni; e se lo facessero tutti?


Potrei bloccare in qualche modo i cambiamenti di orientamento per queste viste? Se l'attività sottostante cambia orientamento, la mia vista cambia anche il suo orientamento.
MG

1
No. Il cambio di orientamento è a livello di dispositivo, non solo per l'attività.
Rob Pridham,

7

Springy heads offre un comportamento basato sulla primavera di chat head out of the box. Tutto quello che devi definire è il disegno per la testa della chat e il frammento da aprire dopo aver fatto clic sulla testa della chat. Le testate della chat si comprimono quando vengono ridotte a icona e seguono il dito quando vengono trascinate.

Il progetto include un'app demo che dimostra tutte le funzionalità integrate. Per usarlo, è necessario aggiungere questo nelle dipendenze di livello.

compile 'com.flipkart.springyheads:library:0.9.6'

Ehi @KiranKumar, hai creato una libreria molto chiara .. Lo adoro .. Sto provando ad imparare vari aspetti da questa libreria .. Ho cercato di eseguirlo fuori dalla finestra dell'applicazione, in qualche modo sono leggermente riuscito a farlo che così .. Ma, il problema sorge quando faccio clic sulla testa della chat fuori dalla finestra dell'app .. il frammento non sarebbe in grado di aprire e restituire java.lang.OutOfMemoryError .. se fosse possibile dalla tua parte a dammi un modo per attraversare questo .. Sarà
felicemente

@arraystack ora puoi eseguirlo in un servizio. Controlla l'elenco se le filiali nel repository GitHub
Kiran Kumar,

@KiranKumar Grazie, il problema con la nuova lib è il permesso dell'applicazione Disegna sulla versione Marshmallow
arraystack
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.