Verbrannt im September 2007. Es war September 2017, als Apple die Mode wieder auf den Markt brachte und das iPhone X vorstellte. Es ist nicht verwunderlich, dass unsere Freunde aus China dieses Design ohne nachzudenken von Apple kopierten (obwohl sich der allererste Mini-Rand noch im Essential Phone befand, das nicht abnahm). Aber was sehen wir jetzt? Huawei P20, Asus Zenfone 5, OnePlus 6, Motorola One Power, Xiaomi Redmi 6 und andere mehr oder weniger bekannte Hersteller produzieren oder kündigen bereits Telefone mit Pony an. Samsung und Google waren die letzten Hochburgen in diesem
Rennen um den Hype- Kampf um Rahmenlosigkeit. Oder nicht? Gerüchten zufolge wird das Google Pixel 3 XL auch
mit diesem Mist einen anmutigen Ausschnitt haben. Nun, wir als Entwickler können ihre Anwendungen nur für diesen Ausschnitt optimieren, damit Benutzer sie weiterhin bequem verwenden können. Ich frage nach Details unter Katze.

Zuerst müssen wir herausfinden, ob die Anwendung überhaupt optimiert werden muss.
Wenn Sie eine Vollbildanwendung haben oder
windowActionBarOverlay = true
im Thema vorhanden ist, wird dies höchstwahrscheinlich benötigt.
Fast alle Anwendungen sind weit von einem einzigen Bildschirm entfernt, und Sie bemerken möglicherweise nicht, wie das Layout auf einem von ihnen aussehen wird. Insbesondere, wenn die Anwendung einen umfangreichen Legacy-Code enthält. Daher sollten Sie immer noch alle Hauptbildschirme durchgehen und überprüfen. Lassen Sie uns herausfinden, was dafür zu tun ist.
1. Bereiten Sie ein Testgerät / einen Emulator vor
Um Ihre Anwendung mit Pony zu testen, benötigen Sie (danke, cap!) Android P. Derzeit ist Android P Preview 5 für die folgenden Geräte verfügbar (dank Project Treble):
Unverzichtbares Telefon
Google Pixel 2;
Google Pixel 2 XL;
Google Pixel
Google Pixel XL
Nokia 7 plus;
OnePlus 6;
Oppo R15 Pro;
Sony Xperia XZ2;
Vivo X21UD;
Vivo X21;
Xiaomi Mi Mix 2S.
Um Android P auf Ihrem Gerät zu installieren, klicken Sie
hier und klicken Sie auf "Get Beta" für Ihr Gerät. Bringen Sie es durch die Luft oder rollen Sie es selbst - Sie haben die Wahl. Die Anweisungen auf der Website sind beigefügt.
Wenn Sie Android P jedoch nicht auf dem Gerät installieren können oder möchten, hat niemand den Emulator abgebrochen. Setup-Anleitung
hier .
2. Schalten Sie den Knall selbst programmgesteuert ein (wenn keine Hardware vorhanden ist).
Hier ist alles einfach: Gehen Sie zu System -> Entwickleroptionen -> Simulieren Sie eine Anzeige mit einem Ausschnitt.
Es stehen 3 Optionen zur Auswahl:

Sie sehen wie folgt aus:
3. Gehen Sie durch die Hauptbildschirme
Natürlich wird dieser Fall für jeden anders sein. Jemand hat eine einfache Logik, jemand nicht. Ich werde einige Beispiele für Bildschirme mit bereistem Layout nennen, die ich in unserer Anwendung gefunden habe.
Entdecken | Profil |
---|
 |  |
Nun wollen wir sehen, wie Layoutfehler behoben werden können.
Ohne compileSdkVersion auszulösen
Beginnend mit der 20-API wurde die
WindowInsets- Klasse
angezeigt , ein
Rect- Objekt, das die zugänglichen und unzugänglichen Teile des Bildschirms beschreibt. Zusammen mit ihnen wurden in View solche Methoden angezeigt, mit denen wir die Koordinaten unzugänglicher Teile des Bildschirms verarbeiten können:
WindowInsets dispatchApplyWindowInsets(WindowInsets); WindowInsets onApplyWindowInsets(WindowInsets); void requestApplyInsets(); void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener);
Details zur Verwendung finden Sie
hier .
Es gibt zwei Möglichkeiten, diese Methoden zu verwenden:
a)
android:fitsSystemWindows="true"
das Tag
android:fitsSystemWindows="true"
in das Layout Ihres Layouts oder Ihrer Ansicht;
b) Mach es aus dem Code:
layout.setFitsSystemWindows(true); layout.requestApplyInsets();
War | Ist geworden |
---|
 |  |
Aktualisieren Sie compileSdkVersion auf Version 28
In naher Zukunft müssen Sie auf diese Version umsteigen. Warum also nicht jetzt darauf vorbereiten? Aber seien Sie vorsichtig, wenn Sie Unit-Tests in Ihrem Projekt haben (und ich hoffe, Sie haben sie), das JUnit-Paket wurde verschoben. Wie es angeschlossen wird, wird
hier beschrieben.
Welche Optionen bietet uns Android P jetzt?
A. WindowManager.LayoutParams hat 3 neue Flags:
Wie bewerbe ich mich?
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
B. Wenn Option A für Sie nicht geeignet ist und Sie den Ort des unglücklichen Ausschnitts berücksichtigen müssen (z. B. wird etwas direkt in der Statusleiste angezeigt, z. B. eine Verbindungsnachricht im Telegramm),
hilft in diesem Fall die neue
DisplayCutout- Klasse.
Betrachten Sie seine Methoden:
Mit ihnen können Sie bereits alles tun, was für die Fantasie ausreicht. Möchten Sie - verschieben Sie den
margin
im Code darauf.
OnApplyWindowInsetsListener
möchten, behandeln Sie es in
OnApplyWindowInsetsListener
und
consumeDisplayCutout()
Sie
consumeDisplayCutout()
. Vielleicht brauchen Sie komplexere Manipulationen. Ich werde ein einfaches Beispiel geben, wie man einen Knall bezeichnet.
class SampleFragment() : Fragment() { private lateinit var root: ViewGroup override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.sample_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) root = view.findViewById(R.id.root) addArrowsToCutout() } private fun addArrowsToCutout() { // , attach window, null' val cutoutList = root.rootWindowInsets?.displayCutout?.boundingRects cutoutList?.forEach { addArrow(context!!.getDrawable(R.drawable.left), it.left.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateLeftArrow) addArrow(context!!.getDrawable(R.drawable.right), it.right.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateRightArrow) addArrow(context!!.getDrawable(R.drawable.top), it.left + (it.right - it.left).toFloat() / 2, it.top.toFloat(), ::calculateTopArrow) addArrow(context!!.getDrawable(R.drawable.bottom), it.left + (it.right - it.left).toFloat() / 2, it.bottom.toFloat(), ::calculateBottomArrow) } } private fun addArrow(arrowIcon: Drawable, x: Float, y: Float, calculation: (View, Float, Float) -> Unit) { val arrowView = ImageView(context) arrowView.setImageDrawable(arrowIcon) arrowView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) root.addView(arrowView) arrowView.post { calculation(arrowView, x, y) } } private fun calculateLeftArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width arrowView.y = y - arrowView.height / 2 } private fun calculateRightArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x arrowView.y = y - arrowView.height / 2 } private fun calculateTopArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y - arrowView.height } private fun calculateBottomArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y } }
Porträt
Landschaft
Wie wir sehen, wird uns der Rand einige Unannehmlichkeiten bereiten und uns dazu bringen, zusätzliche Gesten / zusätzliche Manipulationen vorzunehmen. Im Prinzip ist alles gelöst. Die Hauptsache ist, Layoutmängel so schnell wie möglich zu beseitigen, um genügend Zeit für die Vorbereitung zu haben. Bewältigen Sie Ihre Änderungen erfolgreich. Möge Google sein Spiel nicht brechen!