J'essaie d'obtenir les coordonnées absolues en pixels de l'écran dans le coin supérieur gauche d'une vue. Cependant, toutes les méthodes que je peux trouver telles que getLeft()
et getRight()
ne fonctionnent pas car elles semblent toutes être relatives au parent de la vue, me donnant ainsi 0
. Quelle est la bonne façon de procéder?
Si cela aide, c'est pour un jeu de «remettre l'image en ordre». Je veux que l'utilisateur puisse dessiner une boîte pour sélectionner plusieurs pièces. Mon hypothèse est que la façon la plus simple de le faire est de getRawX()
et getRawY()
vers le MotionEvent
puis de comparer ces valeurs avec le coin supérieur gauche de la mise en page contenant les pièces. Connaissant la taille des pièces, je peux alors déterminer combien de pièces ont été sélectionnées. Je me rends compte que je peux utiliser getX()
et getY()
sur MotionEvent
, mais comme cela renvoie une position relative qui rend plus difficile la détermination des pièces sélectionnées. (Pas impossible, je sais, mais cela semble inutilement compliqué).
Edit: C'est le code que j'ai utilisé pour essayer d'obtenir la taille du conteneur de stockage, selon l'une des questions. TableLayout
est la table qui contient toutes les pièces du puzzle.
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());
Edit 2: Voici le code que j'ai essayé, en suivant plus des réponses suggérées.
public int[] tableLayoutCorners = new int[2];
(...)
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.requestLayout();
Rect corners = new Rect();
tableLayout.getLocalVisibleRect(corners);
Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right
+ ", " + corners.bottom);
cells[4].getLocationOnScreen(tableLayoutCorners);
Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);
Ce code a été ajouté une fois l'initialisation terminée. L'image a été divisée en un tableau d'ImageViews (le tableau de cellules []) contenu dans a TableLayout
. Les cellules [0] sont en haut à gauche ImageView
, et j'ai choisi les cellules [4] car elles se trouvent quelque part au milieu et ne devraient certainement pas avoir de coordonnées (0,0).
Le code ci-dessus me donne toujours tous les 0 dans les journaux, ce que je ne comprends vraiment pas car les différentes pièces du puzzle sont correctement affichées. (J'ai essayé public int pour tableLayoutCorners et la visibilité par défaut, les deux donnant le même résultat.)
Je ne sais pas si c'est important, mais à l' ImageView
origine , les s n'ont pas de taille. La taille du ImageView
s est déterminée automatiquement lors de l'initialisation par la vue lorsque je lui donne une image à afficher. Est-ce que cela pourrait contribuer à ce que leurs valeurs soient 0, même si ce code de journalisation se trouve après avoir reçu une image et se redimensionner automatiquement? Pour potentiellement contrer cela, j'ai ajouté le code tableLayout.requestLayout()
comme indiqué ci-dessus, mais cela n'a pas aidé.
la source
La réponse acceptée ne disait pas comment obtenir l'emplacement, alors voici un peu plus de détails. Vous passez dans un
int
tableau de longueur 2 et les valeurs sont remplacées par les coordonnées (x, y) de la vue (du coin supérieur gauche).Remarques
getLocationOnScreen
pargetLocationInWindow
devrait donner les mêmes résultats dans la plupart des cas (voir cette réponse ). Cependant, si vous êtes dans une fenêtre plus petite comme une boîte de dialogue ou un clavier personnalisé, vous devrez alors choisir celui qui convient le mieux à vos besoins.(0,0)
si vous appelez cette méthodeonCreate
car la vue n'a pas encore été présentée. Vous pouvez utiliser unViewTreeObserver
pour écouter lorsque la mise en page est terminée et vous pouvez obtenir les coordonnées mesurées. (Voir cette réponse .)la source
Vous devez d'abord obtenir le rectangle localVisible de la vue
Par exemple:
J'espère que cela vous aidera
la source
getGlobalVisibleRect()
pour les coordonnées absolues.L'utilisation d'un écouteur de mise en page globale a toujours bien fonctionné pour moi. Il a l'avantage de pouvoir remesurer les choses si la disposition est modifiée, par exemple si quelque chose est réglé sur View.GONE ou que des vues enfants sont ajoutées / supprimées.
la source
setContentView()
causé un problème dans une spécialeActivity
de mon application! C'était une activité de dialogue (windowFrame:@null, windowActionBar:false, windowIsFloating:true, windowNoTitle:true
). Sa disposition principale (aLinearLayout
) n'a pas d'enfant direct avec déterminélayout_width
(tous étaientmatch_parent
ouwrap_content
).Suite au commentaire de Romain Guy, voici comment je l'ai corrigé. J'espère que cela aidera toute autre personne qui a également eu ce problème.
J'essayais en effet d'obtenir les positions des vues avant qu'elles ne soient affichées à l'écran mais ce n'était pas du tout évident que cela se produisait. Ces lignes avaient été placées après l'exécution du code d'initialisation, j'ai donc supposé que tout était prêt. Cependant, ce code était toujours dans onCreate (); en expérimentant avec Thread.sleep (), j'ai découvert que la mise en page n'est réellement finalisée qu'après la fin de l'exécution de onCreate () jusqu'à onResume (). Donc, en effet, le code essayait de s'exécuter avant que la disposition n'ait fini d'être positionnée à l'écran. En ajoutant le code à un OnClickListener (ou à un autre écouteur), les valeurs correctes ont été obtenues car il ne pouvait être déclenché qu'une fois la mise en page terminée.
La ligne ci-dessous a été suggérée comme une modification communautaire:
veuillez utiliser
onWindowfocuschanged(boolean hasFocus)
la source
setContentView(R.layout.something)
, mais elles n'ont pas été chargées visuellement. Ils n'ont ni taille, ni position. Cela ne se produit que lorsque la première passe de mise en page est terminée, ce qui se produit à un moment donné dans le futur (généralement après onResume ()).Première voie:
Dans Kotlin, nous pouvons créer une extension simple pour la vue:
Et obtenez simplement les coordonnées:
Deuxième voie:
La deuxième façon est plus simple:
et obtenir simplement X absolu
view.absX()
et Y parview.absY()
la source
val location = IntArray(2).apply(::getLocationOnScreen)
Mes utilitaires fonctionnent pour obtenir l'emplacement de la vue, il retournera un
Point
objet avecx value
ety value
En utilisant
la source
Vous pouvez obtenir les coordonnées d'une vue en utilisant
getLocationOnScreen()
ougetLocationInWindow()
Ensuite,
x
ety
devrait être le coin supérieur gauche de la vue. Si votre disposition racine est plus petite que l'écran (comme dans une boîte de dialogue), l'utilisationgetLocationInWindow
sera relative à son conteneur, pas à tout l'écran.Solution Java
Pour vous assurer que la vue a pu être mise à jour, exécutez votre demande de localisation une fois que la nouvelle disposition de la vue a été calculée en utilisant
view.post
:~~
Kotlin Solution
Pour vous assurer que la vue a pu être mise à jour, exécutez votre demande de localisation une fois que la nouvelle disposition de la vue a été calculée en utilisant
view.post
:Je recommande de créer une fonction d'extension pour gérer cela:
Et si vous avez besoin de fiabilité, ajoutez également:
la source
Utilisez ce code pour trouver les coordonnées exactes X et Y:
J'ai ajouté / soustrait des valeurs pour ajuster ma vue. Veuillez ne faire ces lignes qu'après avoir gonflé la vue entière.
la source
Afficher à la fois la position et la dimension de l'affichage
la source
En plus des réponses ci-dessus, pour la question où et quand appeler
getLocationOnScreen
?Dans toute information relative à la vue que vous souhaitez obtenir, elle ne sera disponible qu'après que la vue aura été affichée à l'écran. Vous pouvez facilement le faire en mettant votre code qui dépend de la création de la vue à l'intérieur de celui-ci (view.post (Runnable)):
la source