android posizione - Come ottenere le coordinate assolute di una vista




autocad impostare (7)

Per prima cosa devi ottenere il rettangolo visibile locale della vista

Ad esempio:

Rect rectf = new Rect();

//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);

//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);

Log.d("WIDTH        :", String.valueOf(rectf.width()));
Log.d("HEIGHT       :", String.valueOf(rectf.height()));
Log.d("left         :", String.valueOf(rectf.left));
Log.d("right        :", String.valueOf(rectf.right));
Log.d("top          :", String.valueOf(rectf.top));
Log.d("bottom       :", String.valueOf(rectf.bottom));

Spero che questo ti sia d'aiuto

Sto cercando di ottenere le coordinate del pixel dello schermo assoluto nell'angolo in alto a sinistra di una vista. Tuttavia, tutti i metodi che riesco a trovare come getLeft() e getRight() non funzionano in quanto sembrano essere relativi al genitore della vista, dandomi quindi 0 . Qual è il modo corretto per farlo?

Se aiuta, questo è per un gioco "rimetti ordine in ordine". Voglio che l'utente sia in grado di disegnare una casella per selezionare più pezzi. La mia ipotesi è che il modo più semplice per farlo sia ottenere getRawX() e getRawY() da MotionEvent e quindi confrontare questi valori con l'angolo in alto a sinistra del layout che MotionEvent i pezzi. Conoscendo la dimensione dei pezzi, posso determinare quanti pezzi sono stati selezionati. Mi rendo conto che posso usare getX() e getY() sul MotionEvent , ma come quello restituisce una posizione relativa che rende determinante quali pezzi sono stati selezionati più difficili. (Non impossibile, lo so, ma sembra inutilmente complicato).

Modifica: questo è il codice che ho usato per cercare di ottenere le dimensioni del contenitore di attesa, come da una delle domande. TableLayout è la tabella che contiene tutti i pezzi del puzzle.

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());

Modifica 2: Ecco il codice che ho provato, seguendo più delle risposte suggerite.

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]);

Questo codice è stato aggiunto dopo che è stata eseguita l'inizializzazione. L'immagine è stata divisa in una serie di ImageViews (le celle [] array) contenute in un TableLayout . Cells [0] è l' ImageView alto a sinistra e ho selezionato celle [4] poiché si trova da qualche parte nel mezzo e sicuramente non dovrebbero avere le coordinate di (0,0).

Il codice mostrato sopra mi dà ancora tutti gli 0 nei log, che in realtà non capisco perché i vari pezzi del puzzle sono visualizzati correttamente. (Ho provato public int per tableLayoutCorners e la visibilità predefinita, entrambi con lo stesso risultato.)

Non so se questo è significativo, ma i ImageView non hanno inizialmente una dimensione. La dimensione di ImageView viene determinata automaticamente durante l'inizializzazione dalla View quando gli viene data un'immagine da visualizzare. Questo potrebbe contribuire al fatto che i loro valori siano 0, anche se quel codice di registrazione è dopo che è stata loro assegnata un'immagine e si sono ridimensionati automaticamente? Per contrastarlo, ho aggiunto la tableLayout.requestLayout() come mostrato sopra, ma ciò non ha aiutato.


Seguendo il commento di Romain Guy, ecco come l'ho risolto. Speriamo che possa aiutare chiunque abbia avuto questo problema.

Stavo davvero cercando di ottenere le posizioni dei punti di vista prima che fossero disposti sullo schermo, ma non era affatto ovvio che stesse accadendo. Quelle linee erano state posizionate dopo l'esecuzione del codice di inizializzazione, quindi ho pensato che fosse tutto pronto. Tuttavia, questo codice era ancora in onCreate (); sperimentando Thread.sleep () ho scoperto che il layout non è in realtà finalizzato fino a dopo onCreate () fino alla fine dell'esecuzione di onResume (). Quindi, in effetti, il codice stava cercando di funzionare prima che il layout finisse di essere posizionato sullo schermo. Aggiungendo il codice a un OnClickListener (oa qualche altro listener) sono stati ottenuti i valori corretti perché potevano essere attivati ​​solo al termine del layout.

La seguente riga è stata suggerita come modifica della community:

per favore usa onWindowfocuschanged(boolean hasFocus)


Usa questo codice per trovare i coordinati X e Y esatti:

int[] array = new int[2];
ViewForWhichLocationIsToBeFound.getLocationOnScreen(array);
if (AppConstants.DEBUG)
    Log.d(AppConstants.TAG, "array  X = " + array[0] + ", Y = " + array[1]);
ViewWhichToBeMovedOnFoundLocation.setTranslationX(array[0] + 21);
ViewWhichToBeMovedOnFoundLocation.setTranslationY(array[1] - 165);

Ho aggiunto / sottratto alcuni valori per regolare la mia vista. Si prega di fare queste linee solo dopo aver gonfiato l'intera vista.


La mia funzione utils per ottenere la posizione della vista, restituirà un oggetto Point con x value e y value

public static Point getLocationOnScreen(View view){
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    return new Point(location[0], location[1]);
}

utilizzando

Point viewALocation = getLocationOnScreen(viewA);

La risposta accettata in realtà non ha detto come ottenere la posizione, quindi qui c'è un piccolo dettaglio in più. Si passa in un array int di lunghezza 2 e i valori vengono sostituiti con le coordinate della vista (x, y) (in alto a sinistra).

int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];

Gli appunti

  • Sostituire View.getLocationOnScreen() con getLocationInWindow() dovrebbe dare gli stessi risultati nella maggior parte dei casi (vedere questa risposta ). Tuttavia, se ci si trova in una finestra più piccola come una finestra di dialogo o una tastiera personalizzata, utilizzare quindi sarà necessario scegliere quale si adatta meglio alle proprie esigenze.
  • Otterrai (0,0) se chiami questo metodo su onCreate perché la vista non è ancora stata definita. Puoi usare ViewTreeObserver per ascoltare quando il layout è finito e puoi ottenere le coordinate misurate. (Vedi questa risposta .)

Utilizzare un listener di layout globale ha sempre funzionato bene per me. Ha il vantaggio di essere in grado di rimisurare le cose se il layout viene modificato, ad esempio se qualcosa è impostato su View.GONE o le viste figlio vengono aggiunte / rimosse.

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // measure your views here
          }
       }
     );

     setContentView(mainLayout);
 }





android android-tablelayout