Expliquez la frange dans Android P. Que faire avec Android Cutout?

Brûlé en septembre 2007. C'était en septembre 2017, Apple est revenu à la mode en introduisant l'iPhone X. Il n'est pas surprenant que nos amis de Chine, sans y réfléchir à deux fois, aient copié ce design d'Apple (bien que la toute première mini-frange soit toujours dans l'Essential Phone, qui n'a pas décollé). Mais que voyons-nous maintenant? Huawei P20, Asus Zenfone 5, OnePlus 6, Motorola One Power, Xiaomi Redmi 6 et d'autres fabricants plus ou moins connus produisent déjà ou annoncent des téléphones avec frange. Samsung et Google ont été les derniers bastions de cette course au battage médiatique pour le framelessness. Ou pas? Selon les rumeurs, le Google Pixel 3 XL sera également avec cette merde avec un décolleté gracieux. Eh bien, en tant que développeurs, nous ne pouvons qu'optimiser leurs applications pour cette découpe afin que les utilisateurs puissent continuer à les utiliser confortablement. Je demande des détails sous chat.



Tout d'abord, nous devons déterminer si l'application a besoin d'une quelconque optimisation?
Si vous avez une application plein écran ou que windowActionBarOverlay = true présent dans le thème, alors il est très probablement nécessaire.

Presque toutes les applications sont loin d'un seul écran, et vous ne remarquerez peut-être pas comment la mise en page se déroulera sur l'une d'entre elles. Surtout si l'application a un code hérité volumineux. Par conséquent, vous devez toujours parcourir tous les écrans principaux et revérifier. Voyons ce qui doit être fait pour cela.

1. Préparez un appareil de test / émulateur


Pour tester votre application avec une frange, vous avez besoin (merci, casquette!) Android P. Actuellement, Android P Preview 5 est disponible pour les appareils suivants (grâce à Project Treble):
Téléphone essentiel
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.

Pour installer Android P sur votre appareil, cliquez ici et cliquez sur "Obtenir la version bêta" pour votre appareil. Le faire voler dans les airs ou le faire rouler vous-même - à vous de choisir. Les instructions sur le site sont jointes.
Mais si vous ne pouvez pas ou ne souhaitez pas installer Android P sur l'appareil, personne n'a annulé l'émulateur. Instructions de configuration ici .

2. Activez le bang lui-même par programme (s'il n'y a pas de matériel)


Tout est simple ici: allez dans Système -> Options développeur -> Simuler un affichage avec une découpe.
Vous avez le choix entre 3 options:
  • Coin
  • Double
  • Grand


Ils se présentent comme suit:
CoinDoubleGrand

3. Parcourez les écrans principaux


Bien sûr, ce cas sera différent pour tout le monde. Quelqu'un a une logique simple, pas quelqu'un. Je vais vous donner quelques exemples d'écrans avec une mise en page voyagée que j'ai trouvés dans notre application.
ExplorezLe profil

Voyons maintenant quels sont les moyens d'éliminer les défauts de mise en page.

Sans augmenter compileSdkVersion

À partir de l'API 20, la classe WindowInsets est apparue, qui est un objet Rect qui décrit les parties accessibles et inaccessibles de l'écran. Avec eux, de telles méthodes sont apparues dans View que nous pouvons utiliser pour traiter les coordonnées de parties inaccessibles de l'écran:

 WindowInsets dispatchApplyWindowInsets(WindowInsets); WindowInsets onApplyWindowInsets(WindowInsets); void requestApplyInsets(); void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener); 

Les détails sur la façon de les utiliser sont ici .

Il existe deux façons d'utiliser ces méthodes:
a) mettez la balise android:fitsSystemWindows="true" dans la mise en page sur votre mise en page ou vue;
b) faites-le à partir du code:

 layout.setFitsSystemWindows(true); layout.requestApplyInsets(); 

ÉtaitEst devenu

Mettre à niveau compileSdkVersion vers la version 28

Dans un avenir proche, vous devrez passer à cette version, alors pourquoi ne pas vous y préparer maintenant? Mais attention si vous avez des tests unitaires dans votre projet (et j'espère que vous les avez), le package JUnit a bougé. Comment le connecter est décrit ici .

Alors, quelles options Android P nous offre-t-il maintenant?

A. WindowManager.LayoutParams a 3 nouveaux drapeaux:

Comment postuler?

 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 

Si l'option A ne vous convient pas et que vous devez prendre en compte l'emplacement de la coupure malheureuse (par exemple, quelque chose s'affiche à droite dans la barre d'état, comme un message de connexion dans Telegram), alors dans ce cas, la nouvelle classe DisplayCutout vous aidera.
Considérez ses méthodes:

Avec eux, vous pouvez déjà faire tout ce qui est suffisant pour votre imagination. Voulez-vous - déplacer la margin dans le code sur eux. OnApplyWindowInsetsListener souhaitez, gérez-le dans OnApplyWindowInsetsListener et utilisez consumeDisplayCutout() . Vous avez peut-être besoin de manipulations plus complexes. Je vais donner un exemple simple de la façon de désigner un bang.

 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 } } 

Portrait


CoinDoubleGrand


Le paysage


Coin
Double
Grand

Donc, comme nous le voyons, la frange nous apportera quelques inconvénients et nous fera faire des gestes / manipulations supplémentaires. En principe, tout est résolu. L'essentiel est de commencer à éliminer les défauts de mise en page dès que possible afin d'avoir suffisamment de temps pour la préparation. Gérez vos modifications avec succès. Que Google ne casse pas son jeu!

Source: https://habr.com/ru/post/fr419109/


All Articles