De Freeform Window-modus van Android Nougat: wat het is en hoe ontwikkelaars het kunnen gebruiken

De Freeform-modus met meerdere vensters is een onderbenutte en ondergewaardeerde functie in Android Nougat. We leggen uit wat het is en hoe ontwikkelaars het kunnen integreren.

Vrije-vormvenstermodus, zoals voor het eerst gedemonstreerd door Ars Technica

Toen Android 7.0 Nougat begin 2016 voor het eerst werd aangekondigd, bracht het een veelgevraagde functie met zich mee naar het Android-platform: ondersteuning voor meerdere vensters. De meeste mensen zijn zich bewust van de ondersteuning voor meerdere vensters met gesplitst scherm die standaard is ingeschakeld op alle Android Nougat-telefoons en -tablets. Android TV-apparaten met Android Nougat worden geleverd met ondersteuning voor beeld-in-beeld ondersteuning voor meerdere vensters.

Er is echter een derde modus met meerdere vensters aanwezig in Android Nougat waarvan niet veel mensen op de hoogte zijn: vrije vorm venstermodus. In deze modus kan Android apps presenteren als zwevende vensters die door de gebruiker naar wens kunnen worden verplaatst en van formaat kunnen worden aangepast. Het is in wezen de implementatie van Android van a

stapelvensterbeheer.

In de Android SDK-documentatie, het zegt dat:

Fabrikanten van grotere apparaten kunnen ervoor kiezen om de freeform-modus in te schakelen, waarin de gebruiker de grootte van elke activiteit vrijelijk kan aanpassen. Als de fabrikant deze functie inschakelt, biedt het toestel naast de gesplitste schermmodus ook de vrije vormmodus.

En ook in de Android 7.0CDD:

Apparaatimplementaties met schermgrootte xlarge MOETEN de vrije vormmodus ondersteunen.

Dit geeft aan dat elk nieuw Android-apparaat met groot scherm dat wordt geleverd met Android 7.0 mogelijk een vrije-vormvenstermodus kan hebben die door de fabrikant is ingeschakeld.

Dit is echter absoluut geen harde eis. Het is mogelijk om te forceren elk Android Nougat-apparaat (met ontwikkelaarsopties ingeschakeld) om de vrije-vormvenstermodus te ondersteunen met behulp van een van twee verschillende methoden:


Freeform-venstermodus inschakelen op elk Android Nougat-apparaat

Als u de optie 'Forceer dat activiteiten aanpasbaar zijn' inschakelt, kunnen apps op elk apparaat in de vrije-vormmodus worden uitgevoerd

Methode 1 (een computer met adb is vereist)

Zorg ervoor dat USB-foutopsporing is ingeschakeld in de ontwikkelaarsopties. Sluit uw apparaat vervolgens aan op een computer waarop adb is geïnstalleerd en voer de volgende opdracht uit:

adb shell settings put global enable_freeform_support 1

Methode 2 (geen aanvullende vereisten)

Schakel de optie 'Forceer dat de grootte van activiteiten kan worden aangepast' onder aan de ontwikkelaarsopties in.

Voor beide methoden moet de systeeminterface opnieuw worden opgestart voordat ze van kracht kunnen worden. De eenvoudigste manier om dit te doen is door uw apparaat opnieuw op te starten (of, als uw apparaat geroot is, kunt u eenvoudigweg het com.android.systemui proces)


Oké, dus de vrije vormmodus is ingeschakeld… wat nu?

Als u de vrije-vormmodus hebt ingeschakeld met methode 1, is er een nieuwe knop bij app-items in het overzichtsmenu om een ​​app in de vrije-vormvenstermodus te starten.

Met Methode 2 is het echter niet mogelijk om een ​​app via Android zelf in de freeform-modus te starten. Gelukkig, het is voor elk opstartprogramma van derden mogelijk om een ​​app in de vrije-vormvenstermodus te starten met behulp van standaard Android-API's die zijn afgerond als onderdeel van API-niveau 24.

De sleutel tot het starten van een app in de vrije-vormmodus is door de ActivityOptions.setLaunchBounds() methode. Deze methode duurt a Rect als argument, met daarin de venstergrenzen waarmee de app wordt gestart.

Vervolgens kunt u de app starten met startActivity(Intent, Bundle). Als u nog geen ActivityOptions bundel, waarmee u er een kunt maken ActivityOptions.makeBasic() en dan bellen setLaunchBounds() op de vers gemaakte bundel.

Houd er rekening mee dat dit standaard het geval is als er al een taak voor de app aanwezig is in het overzichtsscherm Android zal u eenvoudigweg doorsturen naar de bestaande (volledig scherm) taak die eerder door de gebruiker. U moet alle taken voor de app in Overzicht wissen voordat u probeert de app in een vrije-vormvenster te starten. (Voor apps met activiteiten die starten in standard of singleTop modi kunt u een nieuw venster geforceerd openen door de Intent.FLAG_ACTIVITY_MULTIPLE_TASK markeer de intentie voordat u belt startActivity().)


Hoe werkt de vrije vormmodus onder de motorkap?

Er bestaat een uitstekend artikel geschreven waarin wordt uitgelegd hoe de modus voor meerdere vensters, inclusief de vrije vormmodus, is geïmplementeerd in Android Nougat. (LET OP: het artikel is in het Chinees geschreven, dus zorg ervoor dat u het via Google Translate doorneemt)

Kort gezegd draaien apps in de vrije vormmodus in een aparte stapel van de rest van het systeem (denk aan: virtuele desktop). Daarom is het niet mogelijk dat freeform-apps bovenop het opstartprogramma of op een andere app op volledig scherm worden uitgevoerd.

Apps die in de vrije vormmodus draaien (die dat niet hebben android: windowIsFloating ingesteld op true) hebben een DecorCaptionView toegevoegd als kind van het hoogste niveau DecorView. Deze weergave bevat een LinearLayout het definiëren van de titelbalk van het venster voor het verplaatsen, maximaliseren en sluiten van het venster. Hoewel ik het persoonlijk niet aanbeveel, is het mogelijk om deze weergave te openen en aan te passen door de DecorView gebruik makend van Window.getDecorView(), giet het naar a ViewGroup en vervolgens toegang krijgen tot de onderliggende weergaven.

Elke app die is ontworpen om zich goed te gedragen in de standaard gesplitste schermmodus met meerdere vensters van Android, werkt in de vrije vormmodus. isInMultiWindowMode() retourneert true voor apps die in de vrije vormmodus draaien. Er zijn een paar andere openbaar beschikbare klassen en methoden die een app kan gebruiken en die specifiek betrekking hebben op de vrije vormmodus:

  • Window.setDecorCaptionShade(): deze methode kan worden gebruikt om de tint van de ondertitelingsbesturingselementen (de knoppen voor maximaliseren en sluiten) voor apps in de vrije-vormmodus te overschrijven.
  • Window.setRestrictedCaptionAreaListener(): dit kan worden gebruikt om te detecteren wanneer een venster wordt verplaatst in de vrijevormmodus. De Window.OnRectrictedCaptionAreaChangedListener wordt elke keer aangeroepen wanneer de positie van de ondertitelingsknoppen verandert (wanneer een gebruiker het venster verplaatst), en biedt een Rect met de nieuwe grenzen van de ondertitelingsbesturingselementen.
  • ActivityInfo.WindowLayout: deze klasse bevat informatie die in het manifest van de app is aangegeven over de initiële positionering van een vrije-vormvenster dat een app kan opvragen bij het starten. U kunt bijvoorbeeld het volgende vermelden in de tag van je manifest:
     android: defaultHeight="640dp"
    android: defaultWidth="360dp"
    android: gravity="center" />
    Wanneer het apparaat zich vervolgens al in de vrije vormmodus bevindt en de app wordt gestart, wordt deze gestart met deze gespecificeerde grenzen.

Voorbeelden van vrije-vormvenstermodus in actie

De taakbalk voegt een startmenu en een lade met recente apps toe als aanvulling op de vrije venstermodus

In de zomer van 2016, toen Android Nougat nog een preview voor ontwikkelaars was, bracht ik een app uit met de naam Taakbalk dat een Windows-achtig startmenu en een lijst met recente apps biedt in een systeemoverlay. Hiermee kunnen gebruikers van Nougat apps starten in de vrije-vormvenstermodus - en omdat de taakbalk een overlay gebruikt, kan deze op het scherm blijven in de vrije-vormvensteromgeving. De combinatie van de taakbalk en de vrije vormmodus geeft elk Android-apparaat, vooral tablets, een pc-achtig gevoel.

Jij kan Taakbalk downloaden op Google Play, of bekijk de broncode jezelf op GitHub. Naast de concepten die in dit artikel worden genoemd, gebruik ik ook een paar trucjes om de vrije-vormmodusomgeving actief te houden, zelfs als er geen vrije-vormvensters op het scherm worden weergegeven. Gebruikers kunnen optioneel ook de Taakbalk instellen als hun standaardopstartprogramma, zodat hun apparaat automatisch kan opstarten naar de vrije-vormmodusomgeving.

Aangezien er geen apparaten zijn die officieel worden geleverd met ondersteuning voor freeform-vensters die is ingeschakeld door de OEM (op het moment van schrijven), raad ik aan de taakbalk gebruiken als hulpmiddel voor ontwikkelaars om hun apps te testen in de freeform-vensteromgeving op apparaten die dit anders niet ondersteunen Het.

Naast de Taakbalk heb ik ook de Launcher3-broncode van AOSP aangepast, zodat deze apps in de vrije vormmodus kan starten. Dit is een regelrechte kloon van het standaard Android 7.1.1-opstartprogramma, met de absolute minimale aanpassingen die nodig zijn om freeform-apps te kunnen starten. Ik heb dit aangepaste opstartprogramma geleverd in de hoop dat andere ontwikkelaars ondersteuning voor het starten van vrije-vormvensters in hun aangepaste opstartprogramma's zullen implementeren. Jij kan bekijk de broncode op GitHub, of download een voorbeeld-APK.

Ik hoop dat ontwikkelaars van aangepaste draagraketten deze code kunnen gebruiken en ondersteuning kunnen bieden voor het lanceren van freeform venster-apps voor gebruikers die meer flexibiliteit wensen voor vensterbeheer op hun grote scherm apparaten.