Просмотр getX() и getY() возвращают 0.0 после того, как они были добавлены в Activity
В ManActivity onCreate() я создал новый вид и добавил его через layout.addView к действию. Если я пытаюсь получить getX() или getY() для этого представления, я всегда получаю 0.0.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout main = (RelativeLayout)findViewById(R.id.main);
RelativeLayout.LayoutParams squarePosition = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
GameToken square1 = new GameToken(this,GameToken.SQUARE, fieldHeight,fieldWidth);
squarePosition.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
squarePosition.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
main.addView(square1, squarePosition);
System.out.println(square1.getX()); //Prints '0.0'
System.out.println(square1.getY()); //Prints '0.0'
3 ответа
ViewGroup
такие как RelativeLayout
не размещайте своих детей сразу, и поэтому ваш View еще не знает, где он будет находиться на экране. Вам нужно подождать RelativeLayout
завершить проход макета до того, как это может произойти.
Вы можете прослушивать глобальные события макета следующим образом:
view.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Layout has happened here.
// Don't forget to remove your listener when you are done with it.
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Другой вариант заключается в использовании post(Runnable action)
метод:
view.post(new Runnable() {
@Override
public void run() {
System.out.println(view.getX());
System.out.println(view.getY());
}
});
Это приведет к выполнению Runnable после завершения других ожидающих задач (таких как разметка).
Переместите ваши вызовы getX() и getY() в функцию обратного вызова onWindowFocusChanged(). Как говорится в официальном руководстве, это лучший способ узнать, видна ли активность пользователю. Глядя на ваш код, вы можете поместить свой квадрат в переменные-члены, чтобы иметь возможность использовать его с обоими обратными вызовами.
Попробуй это:
GameToken mSquare1 = new GameToken(this,GameToken.SQUARE, fieldHeight,fieldWidth);
...
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus) {
System.out.println(mSquare1.getX());
System.out.println(mSquare1.getY());
}
}
Общее правило заключается в том, что вы не можете получить информацию о позициях из вашего макета в onCreate(), потому что вы просто создаете его, и Android все равно должен его разработать.
Вы также можете дать возможность обратному вызову onResume(), но для меня это не сработало.