Отображение чата
SDK предоставляет два способа отобразить чат: через ChatFragment (рекомендуется) или через встроенную ChatActivity.
Способ 1: ChatFragment (рекомендуется)
Даёт полный контроль над контейнером, навигацией и жизненным циклом.
- Kotlin
- Java
import edna.chatcenter.core.annotation.OpenWay
import edna.chatcenter.ui.visual.fragments.ChatFragment
class MyChatActivity : AppCompatActivity() {
private val chatCenterUI: ChatCenterUI
get() = (application as MyApp).chatCenterUI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
// getChatFragment() возвращает ранее созданный экземпляр (если он жив в памяти)
// или null. На первом открытии создайте фрагмент через ChatFragment.newInstance(...).
val chatFragment = chatCenterUI.getChatFragment()
?: ChatFragment.newInstance(OpenWay.DEFAULT)
supportFragmentManager
.beginTransaction()
.replace(R.id.chat_container, chatFragment)
.commit()
}
override fun onBackPressed() {
val chatFragment = supportFragmentManager
.findFragmentById(R.id.chat_container) as? ChatFragment
if (chatFragment != null) {
val shouldClose = chatFragment.onBackPressed()
if (shouldClose) {
finish()
}
} else {
super.onBackPressed()
}
}
}
import edna.chatcenter.core.annotation.OpenWay;
import edna.chatcenter.ui.visual.fragments.ChatFragment;
public class MyChatActivity extends AppCompatActivity {
private ChatCenterUI chatCenterUI() {
return ((MyApp) getApplication()).getChatCenterUI();
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
// getChatFragment() возвращает ранее созданный экземпляр (если он жив в памяти)
// или null. На первом открытии создайте фрагмент через ChatFragment.newInstance(...).
ChatFragment chatFragment = chatCenterUI().getChatFragment();
if (chatFragment == null) {
chatFragment = ChatFragment.newInstance(OpenWay.DEFAULT);
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.chat_container, chatFragment)
.commit();
}
@Override
public void onBackPressed() {
ChatFragment chat = (ChatFragment) getSupportFragmentManager()
.findFragmentById(R.id.chat_container);
if (chat != null) {
boolean needsCloseChat = chat.onBackPressed();
if (needsCloseChat) {
finish();
}
} else {
super.onBackPressed();
}
}
}
R.id.chat_container — контейнер FrameLayout в вашей разметке. SDK представляет собой фрагмент — вы можете самостоятельно настроить отступы контейнера.
Метод onBackPressed() помечен как deprecated начиная с API 33 (Android 13). Метод chatFragment.onBackPressed() остаётся актуальным API для обработки навигации внутри SDK. Для современных приложений рекомендуется использовать OnBackPressedDispatcher:
onBackPressedDispatcher.addCallback(this) {
val chatFragment = supportFragmentManager
.findFragmentById(R.id.chat_container) as? ChatFragment
val shouldClose = chatFragment?.onBackPressed() ?: true
if (shouldClose) finish()
}
Способ 2: ChatActivity
Встроенная Activity SDK, уже содержащая ChatFragment и собственный layout. Не требует от приложения отдельной Activity и контейнера-разметки.
import edna.chatcenter.ui.visual.activities.ChatActivity
val intent = Intent(context, ChatActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
Для получения ссылки на текущую Activity:
val activity = chatCenterUI.getChatActivity() // null, если Activity ещё не создана
Сравнение подходов
- ChatFragment — для production-приложений, когда нужен контроль над навигацией, Navigation Component, или встраивание чата в существующий экран
- ChatActivity — когда чат занимает отдельный экран без кастомной навигации и встроенный layout SDK устраивает
Edge-to-edge (Android 15+)
Начиная с Android 15 (targetSdk = 35) подход edge-to-edge стал обязательным: система игнорирует android:fitsSystemWindows и контент по умолчанию рисуется под status bar и navigation bar.
SDK обрабатывает insets автоматически при targetSdk = 35: toolbar и поле ввода получают корректные WindowInsets-отступы без дополнительной настройки.
ChatFlow.fullScreenMode устарелСвойство fullScreenMode в ChatFlow помечено @Deprecated. Согласно сообщению аннотации в коде SDK — «с момента targetSdk = 35 параметр более не используется (всегда true)». Поле оставлено для бинарной совместимости; см. также Известные ограничения (раздел «Поля без эффекта в текущей версии»).
Чат в частичном контейнере (bottom sheet, drawer)
В SDK 5.x на устройствах Android 15+ (API 35+) ChatFragment безусловно применяет WindowInsets-отступы к toolbar и нижнему layout (поле ввода). Публичного флага или escape-hatch для отключения нет.
Поле ChatFlow.fullScreenMode рантаймом SDK не читается (см. Известные ограничения, раздел «Поля без эффекта в текущей версии»). Установка fullScreenMode = false не отключит применение insets.
Что это значит для встраивания в BottomSheetDialogFragment / drawer / partial container: на устройстве с Android 15+ нижний край чата получит padding высотой с системную navigation bar даже внутри bottom sheet, что визуально выглядит как лишний отступ.
Временные обходные пути на стороне приложения (вне SDK):
- Использовать
ChatActivityс собственной темой, либо отдельный полноэкранный экран вместо bottom sheet; - На уровне хост-
ActivityуправлятьWindowCompat.setDecorFitsSystemWindows(window, false)и собственной темой так, чтобы чат всё-таки воспринимался как полноэкранный; - Дождаться публичного API для opt-out — следите за Changelog.
Поля chatCenterUI.theme / darkTheme опрашиваются при каждом создании ChatFragment (в onCreateView). Если изменить тему, пока чат уже открыт, текущий экран автоматически не перерисуется — закройте чат и откройте его заново, новая тема применится. Переинициализация SDK не требуется. См. также Темы.
Обработка кнопки «Назад»
SDK использует внутреннюю навигацию (поиск сообщений, просмотр изображений, выбранные сообщения, цитирование). Всегда передавайте нажатие «Назад» во ChatFragment:
Сигнатура:
fun onBackPressed(): Boolean
Возвращает:
true— чат готов к закрытию (никакая внутренняя навигация не была активна).false— SDK обработал нажатие сам (например, закрыл поисковую строку, снял выделение сообщений, скрыл квоту); хост-экран закрывать не нужно.
val shouldClose = chatFragment.onBackPressed()
if (shouldClose) finish()