Ответ 1
Причина, по которой вы получаете размер 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)
.