Składane urządzenia zapewniają wyjątkowe wrażenia podczas oglądania. Tryb tylnego wyświetlacza i tryb podwójnego ekranu umożliwiają tworzenie specjalnych funkcji wyświetlacza na urządzeniach składanych, takich jak podgląd selfie z tylnego aparatu oraz wyświetlanie kilku różnych wyświetlaczy na ekranach wewnętrznym i zewnętrznym.
Tryb tylnego wyświetlacza
Zazwyczaj, gdy urządzenie składane jest rozłożone, aktywny jest tylko ekran wewnętrzny. Tryb tylnego wyświetlacza pozwala przenieść aktywność na ekran zewnętrzny urządzenia składanego. który zazwyczaj jest skierowany w stronę użytkownika, gdy urządzenie jest rozkładane. Wewnętrzny ekran wyłączy się automatycznie.
Nowatorska aplikacja pozwala wyświetlić podgląd z aparatu na ekranie zewnętrznym. dzięki czemu użytkownicy mogą robić selfie tylnym aparatem, który zwykle pozwala robić zdjęcia znacznie lepiej.
Aby włączyć tryb tylnego wyświetlacza, użytkownik musi odpowiedzieć w oknie, w którym zezwala aplikacji na przełączanie ekranu, na przykład:
Okno tworzy system, więc nie musisz niczego programować. W zależności od stanu urządzenia wyświetlane są różne okna. np. system każe użytkownikom otwierać je, jeśli jest zamknięte. Nie możesz dostosować tego okna, ale może się ono różnić w zależności od urządzenia od różnych dostawców OEM.
Tryb tylnego wyświetlacza możesz wypróbować w aplikacji aparatu Pixel Fold. Zapoznaj się z przykładową implementacją w ramach ćwiczenia z programowania (w języku angielskim) na temat rozwijania działania aparatu.
Tryb Dual Screen
Tryb 2 ekranów umożliwia wyświetlanie treści na obu wyświetlaczach urządzenia składanego jednocześnie. Tryb 2 ekranu jest dostępny na Pixelu Fold z Androidem 14 (poziom interfejsu API 34) lub nowszym.
Przykładem może być korzystanie z funkcji tłumaczenia rozmowy na dwóch ekranach.
Automatyczne włączanie trybów
Dostęp do trybu tylnego wyświetlacza i trybu podwójnego ekranu możesz uzyskać za pomocą interfejsów API Jetpack WindowManager, począwszy od biblioteki w wersji 1.2.0-beta03.
Dodaj zależność WindowManager do pliku build.gradle
modułu aplikacji:
Odlotowe
dependencies { implementation "androidx.window:window:1.2.0-beta03" }
Kotlin
dependencies { implementation("androidx.window:window:1.2.0-beta03") }
Punkt wejścia to WindowAreaController
,
który udostępnia informacje i zachowania związane z przenoszeniem okien między wyświetlaczami lub obszarami wyświetlania na urządzeniu.
WindowAreaController
umożliwia wysyłanie zapytań o listę dostępnych elementów
WindowAreaInfo
.
obiektów.
Użyj adresu WindowAreaInfo
, aby uzyskać dostęp do: WindowAreaSession
,
interfejsu reprezentującego funkcję obszaru aktywnego okna.
Użyj właściwości WindowAreaSession
, aby określić dostępność
WindowAreaCapability
Każda możliwość jest powiązana z konkretnym elementem WindowAreaCapability.Operation
.
W wersjach 1.2.0-beta03 Jetpack WindowManager obsługuje dwa rodzaje operacji:
WindowAreaCapability.Operation.OPERATION_PRESENT_ON_AREA
– służy do uruchamiania trybu Dual ScreenWindowAreaCapability.Operation.OPERATION_TRANSFER_ACTIVITY_TO_AREA
– służy do włączania trybu tylnego wyświetlacza.
Oto przykład deklaracji zmiennych dla trybu tylnego wyświetlacza i trybu Dual Screen w głównej aktywności aplikacji:
Kotlin
private lateinit var windowAreaController: WindowAreaController private lateinit var displayExecutor: Executor private var windowAreaSession: WindowAreaSession? = null private var windowAreaInfo: WindowAreaInfo? = null private var capabilityStatus: WindowAreaCapability.Status = WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNSUPPORTED private val dualScreenOperation = WindowAreaCapability.Operation.OPERATION_PRESENT_ON_AREA private val rearDisplayOperation = WindowAreaCapability.Operation.OPERATION_TRANSFER_ACTIVITY_TO_AREA
Java
private WindowAreaControllerCallbackAdapter windowAreaController = null; private Executor displayExecutor = null; private WindowAreaSessionPresenter windowAreaSession = null; private WindowAreaInfo windowAreaInfo = null; private WindowAreaCapability.Status capabilityStatus = WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNSUPPORTED; private WindowAreaCapability.Operation dualScreenOperation = WindowAreaCapability.Operation.OPERATION_PRESENT_ON_AREA; private WindowAreaCapability.Operation rearDisplayOperation = WindowAreaCapability.Operation.OPERATION_TRANSFER_ACTIVITY_TO_AREA;
Oto jak zainicjować zmienne w metodzie onCreate()
w Twojej aktywności:
Kotlin
displayExecutor = ContextCompat.getMainExecutor(this) windowAreaController = WindowAreaController.getOrCreate() lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowAreaController.windowAreaInfos .map { info -> info.firstOrNull { it.type == WindowAreaInfo.Type.TYPE_REAR_FACING } } .onEach { info -> windowAreaInfo = info } .map { it?.getCapability(operation)?.status ?: WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNSUPPORTED } .distinctUntilChanged() .collect { capabilityStatus = it } } }
Java
displayExecutor = ContextCompat.getMainExecutor(this); windowAreaController = new WindowAreaControllerCallbackAdapter(WindowAreaController.getOrCreate()); windowAreaController.addWindowAreaInfoListListener(displayExecutor, this); windowAreaController.addWindowAreaInfoListListener(displayExecutor, windowAreaInfos -> { for(WindowAreaInfo newInfo : windowAreaInfos){ if(newInfo.getType().equals(WindowAreaInfo.Type.TYPE_REAR_FACING)){ windowAreaInfo = newInfo; capabilityStatus = newInfo.getCapability(presentOperation).getStatus(); break; } } });
Zanim rozpoczniesz operację, sprawdź dostępność konkretnej funkcji:
Kotlin
when (capabilityStatus) { WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNSUPPORTED -> { // The selected display mode is not supported on this device. } WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNAVAILABLE -> { // The selected display mode is not currently available to be enabled. } WindowAreaCapability.Status.WINDOW_AREA_STATUS_AVAILABLE -> { // The selected display mode is currently available to be enabled. } WindowAreaCapability.Status.WINDOW_AREA_STATUS_ACTIVE -> { // The selected display mode is already active. } else -> { // The selected display mode status is unknown. } }
Java
if (capabilityStatus.equals(WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNSUPPORTED)) { // The selected display mode is not supported on this device. } else if (capabilityStatus.equals(WindowAreaCapability.Status.WINDOW_AREA_STATUS_UNAVAILABLE)) { // The selected display mode is not currently available to be enabled. } else if (capabilityStatus.equals(WindowAreaCapability.Status.WINDOW_AREA_STATUS_AVAILABLE)) { // The selected display mode is currently available to be enabled. } else if (capabilityStatus.equals(WindowAreaCapability.Status.WINDOW_AREA_STATUS_ACTIVE)) { // The selected display mode is already active. } else { // The selected display mode status is unknown. }
Tryb Dual Screen
Poniższy przykład zamyka sesję, jeśli funkcja jest już aktywna.
lub w inny sposób wywołuje funkcję presentContentOnWindowArea()
:
Kotlin
fun toggleDualScreenMode() { if (windowAreaSession != null) { windowAreaSession?.close() } else { windowAreaInfo?.token?.let { token -> windowAreaController.presentContentOnWindowArea( token = token, activity = this, executor = displayExecutor, windowAreaPresentationSessionCallback = this ) } } }
Java
private void toggleDualScreenMode() { if(windowAreaSession != null) { windowAreaSession.close(); } else { Binder token = windowAreaInfo.getToken(); windowAreaController.presentContentOnWindowArea( token, this, displayExecutor, this); } }
Zwróć uwagę na to, że WindowAreaPresentationSessionCallback
jest wykorzystywane w głównej aktywności w aplikacji.
Interfejs API wykorzystuje podejście detektora: gdy przesyłasz żądanie prezentacji treści
na ekran urządzenia składanego, inicjujesz sesję, która jest zwracana.
za pomocą metody onSessionStarted()
detektora.
Gdy zamkniesz sesję, w metodzie onSessionEnded()
pojawi się potwierdzenie.
Aby utworzyć odbiornik, zaimplementuj interfejs WindowAreaPresentationSessionCallback
:
Kotlin
class MainActivity : AppCompatActivity(), windowAreaPresentationSessionCallback
Java
public class MainActivity extends AppCompatActivity implements WindowAreaPresentationSessionCallback
Detektor musi zaimplementować onSessionStarted()
, onSessionEnded(),
i onContainerVisibilityChanged()
.
Metody wywołania zwrotnego powiadamiają o stanie sesji i umożliwiają odpowiednie zaktualizowanie aplikacji.
Wywołanie zwrotne onSessionStarted()
otrzymuje WindowAreaSessionPresenter
jako argument.
Ten argument to kontener umożliwiający dostęp do obszaru okna i pokazywanie jego zawartości.
Prezentacja może zostać automatycznie zamknięta przez system, gdy użytkownik opuści główne okno aplikacji. Prezentację można też zamknąć, wywołując metodę WindowAreaSessionPresenter#close()
.
W przypadku pozostałych wywołań zwrotnych dla uproszczenia wystarczy sprawdzić, czy w treści funkcji nie występują błędy, i zapisać stan:
Kotlin
override fun onSessionStarted(session: WindowAreaSessionPresenter) { windowAreaSession = session val view = TextView(session.context) view.text = "Hello world!" session.setContentView(view) } override fun onSessionEnded(t: Throwable?) { if(t != null) { Log.e(logTag, "Something was broken: ${t.message}") } } override fun onContainerVisibilityChanged(isVisible: Boolean) { Log.d(logTag, "onContainerVisibilityChanged. isVisible = $isVisible") }
Java
@Override public void onSessionStarted(@NonNull WindowAreaSessionPresenter session) { windowAreaSession = session; TextView view = new TextView(session.getContext()); view.setText("Hello world, from the other screen!"); session.setContentView(view); } @Override public void onSessionEnded(@Nullable Throwable t) { if(t != null) { Log.e(logTag, "Something was broken: ${t.message}"); } } @Override public void onContainerVisibilityChanged(boolean isVisible) { Log.d(logTag, "onContainerVisibilityChanged. isVisible = " + isVisible); }
Aby zachować spójność w całym ekosystemie, użyj oficjalnej ikony Dual Screen, aby wskazać użytkownikom, jak włączyć lub wyłączyć tryb Dual Screen.
Praktyczny przykład znajdziesz na stronie DualScreenActivity.kt.
Tryb tylnego wyświetlacza
Podobnie jak w przypadku trybu Dual Screen w trybie Dual Screen, ten przykład przedstawia toggleRearDisplayMode()
.
zamyka sesję, jeśli funkcja jest już aktywna,
lub w inny sposób wywołuje funkcję transferActivityToWindowArea()
:
Kotlin
fun toggleRearDisplayMode() { if(capabilityStatus == WindowAreaCapability.Status.WINDOW_AREA_STATUS_ACTIVE) { if(windowAreaSession == null) { windowAreaSession = windowAreaInfo?.getActiveSession( operation ) } windowAreaSession?.close() } else { windowAreaInfo?.token?.let { token -> windowAreaController.transferActivityToWindowArea( token = token, activity = this, executor = displayExecutor, windowAreaSessionCallback = this ) } } }
Java
void toggleDualScreenMode() { if(capabilityStatus == WindowAreaCapability.Status.WINDOW_AREA_STATUS_ACTIVE) { if(windowAreaSession == null) { windowAreaSession = windowAreaInfo.getActiveSession( operation ) } windowAreaSession.close() } else { Binder token = windowAreaInfo.getToken(); windowAreaController.transferActivityToWindowArea(token, this, displayExecutor, this); } }
W takim przypadku wyświetlana aktywność jest używana jako WindowAreaSessionCallback,
Jest to prostsze do wdrożenia, ponieważ wywołanie zwrotne nie otrzymuje osoby prowadzącej
który pozwala na wyświetlanie zawartości w obszarze okna, ale przenosi całą aktywność do innego obszaru:
Kotlin
override fun onSessionStarted() { Log.d(logTag, "onSessionStarted") } override fun onSessionEnded(t: Throwable?) { if(t != null) { Log.e(logTag, "Something was broken: ${t.message}") } }
Java
@Override public void onSessionStarted(){ Log.d(logTag, "onSessionStarted"); } @Override public void onSessionEnded(@Nullable Throwable t) { if(t != null) { Log.e(logTag, "Something was broken: ${t.message}"); } }
Aby zachować spójność w całym ekosystemie, używaj oficjalnej ikony tylnego aparatu, aby wskazać użytkownikom, jak włączyć lub wyłączyć tryb tylnego wyświetlacza.
Dodatkowe materiały
- Ćwiczenie z programowania dotyczące korzystania z aparatu
- Podsumowanie pakietu
androidx.window.area
- Przykładowy kod Jetpack WindowManager:
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Zoptymalizuj aplikację aparatu na urządzeniach składanych dzięki Jetpack WindowManager