Причина, по которой вы получаете размер 0, заключается в том, что макет не будет завершен до тех пор, пока действие не будет полностью создано, то есть все onCreate(), onStart() и onResume() прошли. Самый простой известный мне способ получить точный размер — это вызвать ваш метод после завершения макета, например, с помощью прослушивателя кликов на кнопке. Поскольку кнопка не отображается до тех пор, пока макет не будет завершен, размер должен быть доступен к моменту запуска ее прослушивателя кликов.
Это только предположение, но я думаю, что это сложно сделать именно потому, что они не хотят, чтобы люди возились с размерами макета после того, как система только что закончила раскладку экрана. Если бы они предоставили обратный вызов «onLayoutFinished()», вы могли бы застрять в цикле, если бы вы изменили макет в этом. Например, представьте: макет завершен; onLayoutFinished() вызывается, и вы изменяете там макет; существующий макет теперь недействителен; макет переделан; onLayoutFinished() вызывается снова; ваш код вызывается снова - и так далее.
Другой способ сделать это — создать собственное представление и переопределить метод 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)
.
person
Steve Haley
schedule
19.05.2010