Estou tentando obter as coordenadas absolutas de pixels da tela no canto superior esquerdo de uma visualização. No entanto, todos os métodos que posso encontrar como getLeft()
e getRight()
não funcionam, pois todos parecem ser relativos ao pai da visualização, fornecendo-me assim 0
. Qual é a maneira correta de fazer isso?
Se ajudar, isso é para um jogo de 'colocar a foto de volta em ordem'. Quero que o usuário possa desenhar uma caixa para selecionar várias peças. Minha suposição é que a maneira mais fácil de fazer isso é ir getRawX()
e getRawY()
vir de MotionEvent
e comparar esses valores com o canto superior esquerdo do layout que contém as peças. Conhecendo o tamanho das peças, posso determinar quantas peças foram selecionadas. Sei que posso usar getX()
e getY()
no MotionEvent
, mas como isso retorna uma posição relativa que torna mais difícil determinar quais peças foram selecionadas. (Não é impossível, eu sei, mas parece desnecessariamente complicado).
Edit: Este é o código que eu usei para tentar obter o tamanho do contêiner de retenção, conforme uma das perguntas. TableLayout
é a mesa que contém todas as peças do quebra-cabeça.
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());
Edit 2: Aqui está o código que eu tentei, seguindo mais das respostas sugeridas.
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]);
Este código foi adicionado após toda a inicialização. A imagem foi dividida em uma matriz de ImageViews (a matriz de células []) contida em a TableLayout
. As células [0] estão no canto superior esquerdo ImageView
e eu escolhi as células [4], pois estão em algum lugar no meio e, definitivamente, não devem ter coordenadas de (0,0).
O código mostrado acima ainda me dá todos os 0s nos logs, o que eu realmente não entendo porque as várias peças do quebra-cabeça são exibidas corretamente. (Tentei public int para tableLayoutCorners e visibilidade padrão, ambos dando o mesmo resultado.)
Não sei se isso é significativo, mas os ImageView
s não recebem um tamanho originalmente. O tamanho dos ImageView
s é determinado durante a inicialização automaticamente pela Visualização quando eu mostro uma imagem a ser exibida. Isso poderia contribuir para que seus valores fossem 0, mesmo que o código de registro ocorra depois de receberem uma imagem e se redimensionarem automaticamente? Para potencialmente combater isso, adicionei o código tableLayout.requestLayout()
como mostrado acima, mas isso não ajudou.
fonte
A resposta aceita não revelou como obter o local, então aqui está um pouco mais detalhadamente. Você passa em uma
int
matriz de comprimento 2 e os valores são substituídos pelas coordenadas da vista (x, y) (no canto superior esquerdo).Notas
getLocationOnScreen
porgetLocationInWindow
deve fornecer os mesmos resultados na maioria dos casos (consulte esta resposta ). No entanto, se você estiver em uma janela menor como um Diálogo ou teclado personalizado, use-o para escolher qual deles melhor se adequa às suas necessidades.(0,0)
se você chamar esse métodoonCreate
porque a visualização ainda não foi definida. Você pode usar aViewTreeObserver
para ouvir quando o layout estiver concluído e obter as coordenadas medidas. (Veja esta resposta .)fonte
Primeiro você precisa obter o retângulo localVisible da visualização
Por exemplo:
Espero que isso ajude
fonte
getGlobalVisibleRect()
para cordas absolutas.Usar um ouvinte de layout global sempre funcionou bem para mim. Ele tem a vantagem de poder avaliar novamente as coisas se o layout for alterado, por exemplo, se algo estiver definido como View.GONE ou visualizações filho forem adicionadas / removidas.
fonte
setContentView()
causou um problema em um especialActivity
no meu aplicativo! Essa foi uma atividade de diálogo (windowFrame:@null, windowActionBar:false, windowIsFloating:true, windowNoTitle:true
). Seu layout principal (aLinearLayout
) não tem nenhum filho direto com determinadolayout_width
(todos eles erammatch_parent
ouwrap_content
).Após o comentário de Romain Guy, aqui está como eu o consertei. Espero que ajude qualquer pessoa que também tenha esse problema.
Na verdade, eu estava tentando obter as posições das vistas antes que elas fossem exibidas na tela, mas não era óbvio o que estava acontecendo. Essas linhas foram colocadas após a execução do código de inicialização, então presumi que tudo estivesse pronto. No entanto, esse código ainda estava em onCreate (); experimentando Thread.sleep (), descobri que o layout não é realmente finalizado até depois que onCreate () todo o caminho até onResume () terminar de executar. Então, de fato, o código estava tentando executar antes que o layout terminasse de ser posicionado na tela. Ao adicionar o código a um OnClickListener (ou a algum outro ouvinte), os valores corretos foram obtidos, pois só podiam ser acionados após a conclusão do layout.
A linha abaixo foi sugerida como uma edição da comunidade:
Por favor, use
onWindowfocuschanged(boolean hasFocus)
fonte
setContentView(R.layout.something)
, mas não foram carregadas visualmente. Eles não têm tamanho ou posição. Isso não acontece até que a primeira passagem de layout seja concluída, o que acontece em algum momento no futuro (geralmente após onResume ()).Primeira maneira:
No Kotlin , podemos criar uma extensão simples para visualização:
E simplesmente obtenha coordenadas:
Segunda maneira:
A segunda maneira é mais simples:
e simplesmente obtenha X absoluto
view.absX()
e Y porview.absY()
fonte
val location = IntArray(2).apply(::getLocationOnScreen)
Meus utils funcionam para obter a localização da visualização, ele retornará um
Point
objeto comx value
ey value
Usando
fonte
Você pode obter as coordenadas de uma vista usando
getLocationOnScreen()
ougetLocationInWindow()
Depois,
x
ey
deve ser o canto superior esquerdo da exibição. Se o layout raiz for menor que a tela (como em um Diálogo), o usogetLocationInWindow
será relativo ao contêiner, não à tela inteira.Solução Java
Para garantir que a visualização tenha a chance de atualizar, execute sua solicitação de local após o novo layout da visualização ter sido calculado usando
view.post
:~~
Solução Kotlin
Para garantir que a visualização tenha a chance de atualizar, execute sua solicitação de local após o novo layout da visualização ter sido calculado usando
view.post
:Eu recomendo criar uma função de extensão para lidar com isso:
E se você precisar de confiabilidade, adicione também:
fonte
Use este código para encontrar cordinatos X e Y exatos:
Eu adicionei / subtraí alguns valores para ajustar minha visão. Faça essas linhas somente após a exibição completa ter sido inflada.
fonte
Obter posição e dimensão da vista na tela
fonte
Além das respostas acima, para a pergunta de onde e quando você deve ligar
getLocationOnScreen
?Em qualquer informação relacionada a qualquer visualização que você deseja obter, ela estará disponível apenas após a visualização na tela. Você pode fazer isso facilmente colocando seu código, que depende da criação da view dentro deste (view.post (Runnable)):
fonte