Причина, по которой вы получаете размер 0, заключается в том, что макет не закончен до тех пор, пока не будет полностью создано действие, то есть onCreate (), onStart () и onResume () все прошли. Самый простой способ узнать точный размер, который я знаю, - это вызвать ваш метод после завершения макета, например, с помощью прослушивателя щелчка на кнопке. Поскольку кнопка не отображается до тех пор, пока макет не будет завершен, размер должен быть доступен к моменту запуска прослушивателя щелчков.
Это только предположение, но я представляю, что это трудно сделать именно потому, что они не хотят, чтобы люди вмешивались в размеры компоновки после того, как система только что закончила выкладывать экран. Если бы они предоставили обратный вызов onLayoutFinished (), то вы могли бы застрять в цикле, если изменили макет в этом. Например, представьте: макет завершен; Вызов onLayoutFinished (), и вы измените макет там; существующий макет теперь недействителен; макет переделан; onLayoutFinished () вызывается снова; Ваш код вызывается снова - и так далее.
Еще один способ сделать это - создать пользовательский View и переопределить метод onMeasure(int, int)
. Система вызывает этот метод, чтобы получить размер каждого просмотра; если вы используете что-то вроде моего примера ниже, вы можете получить рекомендуемый размер до окончания макета:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//getMeasuredHeight() and getMeasuredWidth() now contain the suggested size
}
(я написал, что это рекомендуемый размер, потому что я думаю, что размер можно изменить после этого на основе ограничений макета. Однако, это смутное воспоминание о том, что я читал некоторое время назад, и я никогда не экспериментировал в деталях. ) Как только вы это сделаете, вы можете использовать размер для того, что вы хотите сделать - вы даже можете изменить размер, который он будет использовать, используя setMeasuredDimension(newX, newY)
.