Какие API используются для рисования поверх других приложений (например, чатов Facebook)?

226

Как Facebook создает чат-головы на Android? Что такое API для создания плавающих представлений поверх всех остальных представлений?

Даниэль А. Уайт
источник
6
В этом приложении также есть «Головки чата» play.google.com/store/apps/details?id=com.ninja.sms
Оли
11
Если вы ищете пример, см. Github.com/marshallino16/FloatingNotification
marshallino16
5
Вы можете найти демонстрационную версию и простую библиотеку здесь: github.com/ericbhatti/floaties Используя эту библиотеку, вы можете создавать плавающие окна, используя всего две строки.
Эрик Б.
1
github.com/recruit-lifestyle/FloatingView
Анураг-Шарма

Ответы:

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

.. И добавьте эту услугу в свой манифест.

Waza_Be
источник
4
Думаю, есть еще более странные вещи. Как насчет обработки ввода вне «головы», а также перетаскиваемости? Я думаю, что вам, по крайней мере, понадобится FLAG_NOT_TOUCH_MODAL , а также некоторая умная логика для обновления атрибутов окна (т. Е. Перемещения его) во время его перетаскивания.
Делян
2
в том как убрать чаты?
Нирав Мехта
6
Я подумал, что стоит упомянуть SDK, который я разработал для создания плавающего пользовательского интерфейса: www.tooleap.com
Arik
@NiravMehta Вы можете удалить головы чата?
KK_07k11A0585
Как убрать поле чата. Потому что в приведенном выше коде у кружка есть место от границы. В Facebook у пузыря нет этого места
Отладчик
51

Как правило, действия Android представляют собой полноэкранные, концептуально выделенные пользовательские интерфейсы, которые принимают на себя все взаимодействие. Есть несколько исключений из этого. Для начала, есть всплывающие диалоги, которые не заполняют экран. Другой - тост Android, который является неинтерактивным всплывающим окном - вы не можете прикоснуться к нему, и если вы попробуете, то перейдете к тому, что находится под ним.

Вы также можете создавать свои собственные специальные интерфейсы. Вы можете добавить представления непосредственно к WindowManager, указав флаг типа. Вероятно, Chat Heads использует TYPE_PHONE . Есть несколько похожих типов, но цель та же: специальные наложения, которые могут появляться поверх чего-либо еще без присутствия родительского приложения.

Впрочем, это только из-за проблем с взаимодействием. Сначала ваш оверлей будет поглощать все взаимодействие, поэтому не только голова получает события, но вы блокируете взаимодействие со всем, что находится под ним.

Вы настраиваете это поведение, используя LayoutParams . FLAG_NOT_TOUCH_MODALозначает, что события за пределами вашей области отображения идут в базовые интерфейсы. Теперь вы обнаружите, что это работает, но другие плохие вещи все еще случаются, например, кнопки «назад» / «меню» не перенаправляются на приложения, плюс нет клавиатуры. Чтобы решить, что вам нужно FLAG_NOT_FOCUSABLE.

Вы также получаете побочный эффект от не фокусируемого бита, который больше не является приятным взаимодействием с вашим оверлеем, например, нажатия кнопок. Вы можете получить некоторые базовые сенсорные события, на которых вы всегда можете сделать математику, и этого, вероятно, достаточно для руководителей чата. Просто знайте, что это оставляет вас в одиночестве во многих областях, таких как анимация пользовательского интерфейса.

Хороший обзор деталей, включая возможность выборочного потребления взаимодействия, можно найти в этом потоке StackOverflow . В частности, одна из ссылок с ответами в конечном итоге приведет вас сюда , что является хорошим примером проекта. Обратите внимание, что ICS немного изменил то, как это работает, но потоки объясняют это.

Это все общедоступный API-интерфейс, но на самом деле это не похоже на то, что нужно делать как само собой разумеющееся. Документация изобилует ссылками на специальное поведение системных приложений и имеет веские основания; что если бы все это сделали?

Роб Придхам
источник
Могу ли я как-то заблокировать изменения ориентации для этих видов? Если основная деятельность меняет ориентацию, мой взгляд также меняет его ориентацию.
MG
1
Нет. Изменение ориентации распространяется на все устройство, а не только на деятельность.
Роб Придхам
7

Упругие головы дают основанное на весне поведение чат-головок из коробки. Все, что вам нужно определить - это нарисовать заголовок чата и фрагмент, который открывается после щелчка по заголовку чата. Головки чата сворачиваются при сворачивании и следуют за пальцем при перетаскивании.

Проект включает в себя демонстрационное приложение, которое демонстрирует все встроенные функции. Чтобы использовать его, вам нужно добавить это в ваши зависимости gradle.

compile 'com.flipkart.springyheads:library:0.9.6'
Киран Кумар
источник
Привет @KiranKumar, вы создали очень понятную библиотеку .. Мне просто нравится это .. Я пытаюсь изучить различные аспекты этой библиотеки .. Я пытался запустить ее за пределами окна приложения, так или иначе, я немного преуспел в этом это так ... Но проблема возникает, когда я щелкаю заголовок чата за пределами окна приложения ... фрагмент не сможет открыться и вернуть java.lang.OutOfMemoryError .. если это будет возможно с вашей стороны, чтобы дайте мне немного пути через это .. Это будет с удовольствием выполнено ..
arraystack
@arraystack теперь вы можете запустить его в службе. Проверьте список, если филиалы в репозитории GitHub
Киран Кумар
@KiranKumar Спасибо, проблема с новой библиотекой - разрешение приложения Draw over в
Зефирной