他のアプリ(Facebookのチャットヘッドなど)の上に描画するために使用されるAPIは何ですか?


226

FacebookはAndroidでチャットヘッドをどのように作成しますか?他のすべてのビューの上にフローティングビューを作成するためのAPIは何ですか?


6
このアプリには「チャットヘッズ」play.google.com/store/apps/details?id=com.ninja.sms
Oli

11
例を探している場合は、github.com
marshallino16

5
デモと簡単なライブラリは、こちらにあります:github.com/ericbhatti/floatiesこのライブラリを使用すると、2行だけでフローティングウィンドウを作成できます。
Eric B.

回答:


217

これ

他のすべてのアプリケーションの上に表示されるタイプTYPE_SYSTEM_ALERTを使用して、アプリケーションがウィンドウを開くことを許可します。この許可を使用する必要があるアプリケーションはほとんどありません。これらのウィンドウは、ユーザーとのシステムレベルの対話を目的としています。

定数値:「android.permission.SYSTEM_ALERT_WINDOW」

//編集:完全なコードはここにあります

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

なんとかしてサービスを開始することを忘れないでください:

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

..そして、このサービスをマニフェストに追加します。


4
もっと変なものがあると思う。「頭」の外の入力とドラッグ可能性の扱いについてはどうですか?少なくともFLAG_NOT_TOUCH_MODALと、ドラッグ中にウィンドウの属性を更新(つまり移動)するための賢いロジックが必要だと思います。
Delyan 2013

2
その中でチャットヘッドを削除する方法?
Nirav Mehta 2014

6
私がフローティングUIを作成するために開発したSDKについて言及する価値があると思いました:www.tooleap.com
Arik

@NiravMehtaチャットヘッドを削除できますか?
KK_07k11A0585

チャットヘッドのマージンを削除する方法。上記のコード出力では、円がボーダーからのスペースを持っているため。Facebookでは、バブルにそのスペースがありません
デバッガ

51

原則として、Androidアクティビティはフルスクリーンであり、概念的にはすべての操作を行う専用のUIです。これにはいくつかの例外があります。まず、画面いっぱいに表示されないポップアップダイアログがあります。もう1つはAndroidトーストです。これは非インタラクティブなポップアップです。タッチすることはできません。試してみると、その下にあるものに移動します。

独自の特別なUIも実行できます。WindowManagerタイプフラグを指定して、ビューをに直接追加できます。チャットヘッドはおそらくTYPE_PHONEを使用します。類似するタイプはいくつかありますが、目的は同じです。親アプリケーションが存在しないように見えなくても、何よりも上に表示できる特別な目的のオーバーレイです。

しかし、相互作用の問題のために、それはあなたを今のところ得るだけです。最初に、オーバーレイはすべてのインタラクションを吸収するため、ヘッドはイベントを取得するだけでなく、その下のすべてへのインタラクションをブロックします。

この動作は、LayoutParamsを使用して構成します。FLAG_NOT_TOUCH_MODALは、表示領域外のイベントが基になるUIに移動することを意味します。これで機能することがわかりますが、それでも他の問題が発生します。たとえば、戻る/メニューボタンがアプリに誘導されず、キーボードもありません。それを解決するには、あなたが必要FLAG_NOT_FOCUSABLEです。

フォーカスできないビットからも副作用が発生します。これは、ボタンを押すなど、オーバーレイとのやり取りがうまくいかなくなったためです。ただし、いくつかの基本的なタッチイベントを取得できます。これはいつでも計算を実行でき、チャットヘッドにはこれで十分です。UIアニメーションのように、多くの領域で自分自身を残すことに注意してください。

選択的なインタラクションの消費を可能にするなど、詳細の優れた概要は、このStackOverflowスレッドにあります。特に、回答リンクの1つが最終的にここに移動します。これは良いサンプルプロジェクトです。ICSがこれがどのように機能するかを少し変更しましたが、スレッドがそれを説明していることに注意してください。

これはすべてパブリックAPIに関するものですが、当然のことながら実際に行うべき主流のようには思えません。ドキュメントには、特別なシステムアプリの動作への参照が含まれており、それには十分な理由があります。誰もがそれをしたとしたら?


これらのビューの方向の変更を何らかの方法でブロックできますか?根底にある活動が方向を変えると、私の見方も彼の方向を変える。
MG

1
いいえ。向きの変更は、アクティビティだけでなく、デバイス全体で行われます。
Rob Pridham 2013

7

弾力性のあるヘッドは、チャットベースのスプリングベースの動作を箱から出します。定義する必要があるのは、チャットヘッドのドローアブルと、チャットヘッドをクリックすると開くフラグメントです。チャットヘッドは最小化すると折りたたまれ、ドラッグすると指に追従します。

プロジェクトには、すべての組み込み機能を示すデモアプリが含まれています。これを使用するには、これをgradleの依存関係に追加する必要があります。

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

こんにちは@KiranKumar、あなたは非常に明確なライブラリを作成しました..私はそれが大好きです..このライブラリからさまざまな側面を学ぼうとしています..アプリケーションウィンドウの外で実行しようとしていますが、どういうわけか私はやや成功していますしかし、アプリのウィンドウの外側にあるチャットヘッドをクリックすると、問題が発生します。フラグメントが開いてjava.lang.OutOfMemoryErrorを返すことができません。これを介していくつかの方法を教えてください..それは喜んで光栄に思います..
arraystack

@arraystackをサービスで実行できるようになりました。GitHubリポジトリのブランチのリストを確認してください
Kiran Kumar

@KiranKumarありがとう、新しいlibの問題は、マシュマロバージョンでのアプリケーションの描画の許可です
arraystack
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.