Oversigt
Nogle apps er designet til kun at køre i landskab, f.eks. en kamerastation på en tablet. Brugerne forventer stadig, at billedet vender rigtigt, uanset hvordan de placerer enheden: med knapperne til venstre eller til højre.
KlugLayout sætter Android-skærmorienteringen til landskab på begge sider. Appen forbliver i landskab, men drejer 180 grader med enheden. Den rapporterer også den aktuelle skærmrotation, så en app kan tilpasse sit eget indhold, f.eks. et kamerabillede, til den måde, enheden holdes på.
Foldables ændrer skærmen, mens appen kører. En Galaxy Z Fold eller Pixel Fold er en tablet, når den er åben, og en telefon, når den er lukket; en Galaxy Z Flip skifter fra sin høje hovedskærm til en lille, næsten kvadratisk coverskærm. Når enheden flytter appen til den anden skærm, modtager AIR-stagen ikke altid en resize-hændelse, og startværdierne for skærmstørrelse og kamera-cutout forbliver dem fra den første skærm. KlugLayout overvåger dette natively og fortæller appen, hvilken slags skærm den er på nu.
KlugLayout er i daglig brug i vores apps på Android-tablets, vores proof of concept.
Foldables
KlugLayout sorterer det aktuelle vindue i en af tre klasser og sender en hændelse, hver gang klassen ændres:
| tablet | Den store skærm. Eksempel: en åbnet Galaxy Z Fold eller Pixel Fold. |
| phone | En skærm i telefonstørrelse. Eksempel: en lukket Fold eller hovedskærmen på en Flip. |
| cover | En lille yderskærm. Eksempel: coverskærmen på en Galaxy Z Flip. |
Når en Fold lukkes, suspenderes landskabslåsen, så yderskærmen i telefonstørrelse kan bruge portræt, og den vender tilbage, når enheden åbnes igen. Appen får også størrelsen og kamera-cutouttet for den aktuelle skærm, så et layout bygget efter foldning passer til den skærm, det vises på.
I vores apps logger visningssiden ud og ind igen ved hvert fold- eller coverskifte, så live streams altid starter rent på den nye skærm. På Flip-coveret er brugerfladen lagt ud til en almindelig telefon og skaleret ned, så den passer.
Testet i Android-emulatoren på enhedsprofilerne Pixel 9 Pro Fold og Galaxy Z Flip.
iPhone Duo
iPhone Duo er Apples første foldable: en telefon, når den er lukket, en lille tablet, når den er åben. AIR følger den ikke af sig selv. Når enheden åbnes, kan iOS holde appen i dens letterboxede telefonvindue, ingen resize-hændelse ankommer, og startskærmværdierne forbliver dem fra yderskærmen.
KlugLayout registrerer på iOS, hvilken skærm appen er på, og sender den samme DEVICE_TYPE_CHANGED-hændelse som på Android: "phone", når Duo er lukket, "tablet", når den er åben. Den samme kode betjener begge platforme.
Status: de grundlæggende layouts er løst. Lukkede og åbne layouts, foldning og udfoldning, mens appen kører, rotation af den åbne enhed og centrerede native dialoger virker. Streaming- og kameraindstillinger skal stadig testes på den rigtige enhed.
Der er ingen grund til at vente på AIR 52: fra april 2027 skal App Store-uploads bygges med iOS 27 SDK, og fra da møder en AIR-app iPhone Duo som den foldable, den er. KlugLayout håndterer det allerede i dag, med AIR 51.4.1.
Testet i Xcode 27-simulatoren (iPhone Duo) med HARMAN AIR 51.4.1.
Funktioner
- Selvstændig: én ANE, intet kernebibliotek eller afhængige ANE'er at tilføje
- Landskab på begge sider, drejer med enheden
- Fold-registrering: tablet, phone eller Flip-coverskærm, med en hændelse ved hver ændring
- iPhone Duo: phone, når den er lukket, tablet, når den er åben, med den samme hændelse som på Android
- Landskabslåsen frigives automatisk, mens en Fold er lukket
- Størrelse og kamera-cutout for den aktuelle skærm, også efter foldning
- Intet skift til portræt
- Aktuel skærmrotation: 0, 90, 180 eller 270 grader
- Aktiv fra appens start
- Gør intet på andre platforme, så koden kan blive i en cross-platform-app
Understøttede platforme
Kom i gang
Tilføj udvidelsen til din applikationsdescriptor:
<extensions>
<extensionID>com.klug.layout</extensionID>
</extensions>
Apps, der målretter Android 16, bør også tillade en fast orientering på store skærme med denne property inde i <application> i manifest-tilføjelserne:
<property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true"/>
Kodeeksempler
Fire komplette flows, taget fra den API, der kører i vores apps. Kald vender straks tilbage; skærmændringer ankommer som en StatusEvent. Fuld dokumentation →
import com.klug.layout.KlugLayout; import flash.display.StageAspectRatio; import flash.events.StageOrientationEvent; var layout:KlugLayout = KlugLayout.getInstance(); // isSupported is false on desktop platforms: every call below is then a no-op, // so this code can stay in a cross-platform app stage.autoOrients = true; stage.setAspectRatio( StageAspectRatio.LANDSCAPE ); // first AIR's landscape ... layout.setSensorLandscape(); // ... then both sides on Android // (on iOS LANDSCAPE already allows both sides) // turn your own content, such as a camera picture, with the device updatePicture(); stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGE, function( e:StageOrientationEvent ):void { updatePicture(); }); function updatePicture():void { var rotation:int = layout.displayRotation; // 0, 90, 180 or 270; -1 = unknown if ( rotation != -1 ) rotateCameraPicture( rotation ); // your app function }
import flash.events.StatusEvent; layout.addEventListener( StatusEvent.STATUS, onLayout ); layout.watchFold( stage ); // pass the stage: iOS needs it for the iPhone Duo // events report changes only; read the class once for the start var startClass:String = layout.deviceClass; // "phone", "tablet", "cover" or "" (unknown) showLayoutFor( startClass != "" ? startClass : chooseFromStage() ); // your own default function onLayout( e:StatusEvent ):void { if ( e.code != KlugLayout.DEVICE_TYPE_CHANGED ) return; showLayoutFor( e.level ); // "tablet" or "phone"; "cover" on a Galaxy Z Flip (Android) } // fold-only behaviour, kept away from normal phones and tablets if ( layout.isFoldable ) enableFoldHints(); // your app function
function showLayoutFor( deviceClass:String ):void { // size of the current window in pixels, also after the device moved the app // to its other display; -1 = unknown, then fall back to the stage var w:int = layout.windowWidth > 0 ? layout.windowWidth : stage.stageWidth; var h:int = layout.windowHeight > 0 ? layout.windowHeight : stage.stageHeight; // top inset of the current display (Android: camera cutout, from Android 9) var top:int = Math.max( 0, layout.safeInsetTop ); // -1 = unknown if ( deviceClass == "tablet" ) buildTabletViews( w, h, top ); // your app functions else { buildPhoneViews( w, h, top ); if ( deviceClass == "cover" ) scaleToFit( w, h ); // phone layout, scaled down } }
// while a Fold is closed the lock is suspended on its own and comes back when it is opened. // release() is for screens where the app itself leaves landscape (Android; no-op on iOS). function openPortraitScreen():void { layout.release(); // remove the landscape lock stage.setAspectRatio( StageAspectRatio.PORTRAIT ); // AIR decides again } function openStationScreen():void { stage.setAspectRatio( StageAspectRatio.LANDSCAPE ); layout.setSensorLandscape(); // both landscape sides again }
API-oversigt
| KlugLayout.getInstance() | Returnerer den enkelte instans. |
| isSupported | Sand på Android og iOS. Falsk andre steder; hvert kald er så en no-op. |
| setSensorLandscape() | Landskab på begge sider, drejer med enheden. Kald den efter stage.setAspectRatio(StageAspectRatio.LANDSCAPE). Android; på iOS tillader LANDSCAPE allerede begge sider. |
| displayRotation | Den aktuelle skærmrotation i grader (0, 90, 180, 270), eller -1. |
| watchFold( stage ) | Begynder at overvåge fold- og coverskærmændringer, også uden landskabslås. På iOS kræves stagen til iPhone Duo. |
| isFoldable | Sand på foldbar hardware: Android-foldables (Android 11 eller nyere) og iPhone Duo. |
| release() | Fjerner landskabslåsen, f.eks. når appen skifter til et telefonlayout. Android; no-op på iOS. |
| deviceClass | Den aktuelle klasse: "phone", "tablet" eller "cover"; "" mens den er ukendt. På iOS tilgængelig efter watchFold(stage) på iPhone Duo. |
| windowWidth / windowHeight | Størrelsen på det aktuelle vindue i pixels, følger enheden til dens anden skærm; -1, når den er ukendt. |
| safeInsetTop | Øvre inset for den aktuelle skærm i pixels: kamera-cutouttet på Android (Android 9 eller nyere), det øvre safe area på iOS; -1, når det er ukendt. |
| DEVICE_TYPE_CHANGED | StatusEvent-kode, der sendes ved hver ændring af klassen. |
Events
| deviceTypeChanged | phone · tablet · cover (cover: Galaxy Z Flips yderskærm, Android). Sendes efter watchFold(stage), på Android også efter setSensorLandscape(); kun ved ændringer. |
Køb KlugLayout
En årlig licens til én AIR-applikation, med alle opdateringer i 12 måneder. Efter betaling modtager du udvidelsen, ActionScript-biblioteket og dokumentationen pr. e-mail, normalt inden for én hverdag. Licens og vilkår
- Licens til én AIR-applikation
- Alle opdateringer i 12 måneder
- Svar pr. e-mail inden for 7 dage
- Licens til én AIR-applikation
- Alle opdateringer i 12 måneder
- Svar pr. e-mail inden for 48 timer
Krav
| AIR SDK | 51.x (HARMAN) |
| Android | Android 6.0 (API 23) eller nyere; kamera-cutout fra Android 9 (API 28) |
| iOS | iOS 13 eller nyere; iPhone Duo testet med AIR 51.4.1 |
| Tilladelser | Ingen |