getLocationOnScreen () vs getLocationInWindow ()

Quelle est la différence entre l’écran et la vue dans le contexte de ces deux méthodes?

J’ai un bouton et je veux obtenir la coordonnée x de son centre.

Je suppose que cela suffirait:

public int getButtonXPosition() { return (button.getLeft()+button.getRight())/2; } 

mais alors, quelle différence cela ferait-il si j’avais utilisé

getLocationOnScreen() ou getLocationInWindow() ?

(en ajoutant la moitié de la largeur du bouton à cela, bien sûr)

Je ne pense pas que cette réponse soit correcte. Si je crée un nouveau projet et que je ne modifie que MainActivity en ajoutant l’extrait suivant:

 public boolean dispatchTouchEvent(MotionEvent ev) { View contentsView = findViewById(android.R.id.content); int test1[] = new int[2]; contentsView.getLocationInWindow(test1); int test2[] = new int[2]; contentsView.getLocationOnScreen(test2); System.out.println(test1[1] + " " + test2[1]); return super.dispatchTouchEvent(ev); } 

Je vais voir imprimé à la console 108 108 . Cela utilise un Nexus 7 en cours d’exécution 4.3. J’ai des résultats similaires en utilisant des émulateurs exécutant des versions Android aussi loin que 2.2.

Les fenêtres d’activité normales auront FILL_PARENTxFILL_PARENT comme leur WindowManager.LayoutParams, ce qui les amènera à la taille de l’écran entier. La fenêtre est disposée en dessous (en ce qui concerne l’ordre z, pas les coordonnées y) de la barre d’état et d’autres décorations, donc je pense qu’un tableau plus précis serait:

 |--phone screen-----activity window---| |--------status bar-------------------| | | | | |-------------------------------------| 

Si vous parcourez la source de ces deux méthodes, vous verrez que getLocationInWindow traverse la hiérarchie des vues de votre vue jusqu’à RootViewImpl, en additionnant les coordonnées de la vue et en soustrayant les décalages de défilement des parents. Dans le cas que j’ai décrit ci-dessus, ViewRootImpl obtient la hauteur de la barre d’état à partir de WindowSession et la transmet via fitSystemWindows à ActionBarOverlayLayout, qui ajoute cette valeur à la hauteur de la barre d’action. ActionBarOverlayLayout prend alors cette valeur additionnée et l’applique à sa vue de contenu, qui est le parent de votre mise en page, en tant que marge.

Ainsi, votre contenu est présenté plus bas que la barre d’état, car la fenêtre ne commence pas par une coordonnée y inférieure à celle de la barre d’état, mais par une marge appliquée à la vue du contenu de votre activité.

Si vous getLocationOnScreen source getLocationOnScreen vous la verrez simplement appeler getLocationInWindow , puis append les getLocationInWindow gauche et supérieure de Windows (qui sont également transmises à View par ViewRootImpl, qui les récupère depuis WindowSession). Dans le cas normal, ces valeurs seront toutes deux nulles. Il existe certaines situations où ces valeurs peuvent être non nulles, par exemple une fenêtre de dialog placée au milieu de l’écran.


Donc, pour résumer: une fenêtre d’activité normale remplit tout l’écran, même l’espace sous la barre d’état et les décorations. Les deux méthodes en question renverront les mêmes coordonnées x et y. Ce n’est que dans des cas particuliers, tels que les dialogs où la fenêtre est réellement décalée, que ces deux valeurs diffèrent.

getLocationOnScreen () obtiendra l’emplacement basé sur l’ écran du téléphone .

getLocationInWindow () obtiendra l’emplacement en fonction de la fenêtre d’activité .

Pour l’ activité normale ( activité non plein écran), la relation avec l’écran du téléphone et la fenêtre d’activité est la suivante:

| – écran de téléphone ——————— |
| ——– barre d’état ——————— |
| |
| ——————————————- |
| ——– fenêtre d’activité —— ——- |
| |
| |
| |
| |
| |
| |
| ——————————————- |

Pour les coordonnées x, la valeur des deux méthodes est généralement la même.

Pour la coordonnée y, les valeurs ont une différence pour la hauteur de la barre d’état

La réponse actuellement acceptée est un peu verbeuse. Voici un plus court.

getLocationOnScreen() et getLocationInWindow() renvoient normalement les mêmes valeurs. C’est parce que la fenêtre a normalement la même taille que l’écran. Cependant, la fenêtre est parfois plus petite que l’écran. Par exemple, dans un Dialog ou un clavier système personnalisé.

Donc, si vous savez que les coordonnées que vous voulez sont toujours relatives à l’écran (comme dans une activité normale), vous pouvez utiliser getLocationOnScreen() . Toutefois, si votre vue se trouve dans une fenêtre pouvant être plus petite que l’écran (comme dans un dialog ou un clavier personnalisé), utilisez getLocationInWindow() .

en relation

  • Comment obtenir les coordonnées