У меня есть представление, состоящее из TableLayout, TableRow and TextView
. Я хочу, чтобы это выглядело как сетка. Мне нужно получить высоту и ширину этой сетки. Методы getHeight()
иgetWidth()
всегда возвращают 0. Это происходит, когда я динамически форматирую сетку, а также когда я использую версию XML.
Как получить размеры для вида?
Вот моя тестовая программа, которую я использовал в Debug для проверки результатов:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TableLayout;
import android.widget.TextView;
public class appwig extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maindemo); //<- includes the grid called "board"
int vh = 0;
int vw = 0;
//Test-1 used the xml layout (which is displayed on the screen):
TableLayout tl = (TableLayout) findViewById(R.id.board);
tl = (TableLayout) findViewById(R.id.board);
vh = tl.getHeight(); //<- getHeight returned 0, Why?
vw = tl.getWidth(); //<- getWidth returned 0, Why?
//Test-2 used a simple dynamically generated view:
TextView tv = new TextView(this);
tv.setHeight(20);
tv.setWidth(20);
vh = tv.getHeight(); //<- getHeight returned 0, Why?
vw = tv.getWidth(); //<- getWidth returned 0, Why?
} //eof method
} //eof class
getHeight()
иgetWidth()
после того, как жизненный цикл Activity попросил представления измерить себя, другими словами, сделать что-то подобноеonResume()
и все. Вы не должны ожидать, что еще не выложенный объект будет знать свои размеры, вот и вся хитрость. Нет необходимости в магии, предложенной ниже.getHeight()/Width()
вonResume()
не поддавались> 0 значения для меня.Ответы:
Я считаю, что ОП уже давно нет, но в случае, если этот ответ поможет будущим поисковикам, я подумал, что опубликую найденное мной решение. Я добавил этот код в свой
onCreate()
метод:ИЗДАН: 07/05/11, чтобы включить код из комментариев:
Сначала я получаю окончательную ссылку на свой
TextView
(для доступа вonGlobalLayout()
методе). Затем я получаюViewTreeObserver
от myTextView
и добавляюOnGlobalLayoutListener
переопределениеonGLobalLayout
(здесь, похоже, нет метода суперкласса для вызова здесь ...) и добавляю свой код, который требует знания измерений представления в этом слушателе. У меня все работает как положено, поэтому надеюсь, что это поможет.источник
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
таким образом, слушатель должен быть удален после первого раза такое случается.addOnLayoutChangeListener
работает также! :)Я просто добавлю альтернативное решение, переопределю метод onWindowFocusChanged вашей деятельности, и вы сможете получать значения getHeight (), getWidth () оттуда.
источник
ViewTreeObserver
.Вы пытаетесь получить ширину и высоту элементов, которые еще не были нарисованы.
Если вы используете отладку и остановитесь в какой-то момент, вы увидите, что экран вашего устройства все еще пуст, это потому, что ваши элементы еще не прорисованы, поэтому вы не можете получить ширину и высоту чего-либо, что еще не существует.
И, возможно, я ошибаюсь, но
setWidth()
не всегда соблюдаю,Layout
выкладываю свои дочерние элементы и решаю, как их измерить (вызываяchild.measure()
), поэтому, если вы установитеsetWidth()
, вы не гарантированно получите эту ширину после отрисовки элемента.Что вам нужно, это использовать
getMeasuredWidth()
(самый последний показатель вашего вида) где-то после того, как вид был нарисован.Посмотрите в
Activity
жизненный цикл, чтобы найти лучший момент.http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Я считаю, что хорошей практикой является использование
OnGlobalLayoutListener
так:Вы можете разместить этот код прямо в
onCreate()
, и он будет вызван, когда будут размечены представления.источник
Используйте метод сообщения View, как этот
источник
Я пытался использовать
onGlobalLayout()
для некоторого пользовательского форматирования aTextView
, но, как заметил @George Bailey,onGlobalLayout()
он действительно вызывается дважды: один раз на начальном пути макета и второй раз после изменения текста.View.onSizeChanged()
работает лучше для меня, потому что, если я изменю текст там, метод вызывается только один раз (во время прохождения макета). Это требует подклассаTextView
, но на уровне API 11+View. addOnLayoutChangeListener()
можно использовать, чтобы избежать подкласса.Еще одна вещь, чтобы получить правильную ширину вида
View.onSizeChanged()
,layout_width
должна быть установленаmatch_parent
, а неwrap_content
.источник
Вы пытаетесь получить размеры в конструкторе или любом другом методе, который запускается ДО того, как вы получите реальную картинку?
Вы не получите никаких измерений, пока все компоненты не будут измерены (так как ваш xml не знает о размере вашего дисплея, родительских позициях и т. Д.)
Попробуйте получить значения после onSizeChanged () (хотя его можно вызвать с нуля) или просто подождите, когда вы получите реальное изображение.
источник
Как уже упоминалось FX, вы можете использовать
OnLayoutChangeListener
для представления, что вы хотите отслеживать себяВы можете удалить слушателя в обратном вызове, если вы хотите только первоначальный макет.
источник
Я думаю, это то, на что вам нужно обратить внимание: использование
onSizeChanged()
вашего взгляда. Вот расширенный фрагмент кода о том, как использоватьonSizeChanged()
для динамического получения высоты и ширины макета или представления http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions.htmlисточник
ViewTreeObserver
иonWindowFocusChanged()
вовсе не нужны.Если вы надуете
TextView
как макет и / или поместите в него какой-то контент и установите,LayoutParams
то вы можете использоватьgetMeasuredHeight()
иgetMeasuredWidth()
.НО вы должны быть осторожны
LinearLayouts
(может быть, и другиеViewGroups
). Проблема в том, что вы можете получить ширину и высоту после этого,onWindowFocusChanged()
но если вы попытаетесь добавить в него некоторые виды, то вы не сможете получить эту информацию, пока все не будет нарисовано. Я пытался добавить несколькоTextViews
к,LinearLayouts
чтобы имитироватьFlowLayout
(стиль упаковки) и поэтому не мог использоватьListeners
. Как только процесс запущен, он должен продолжаться синхронно. Поэтому в таком случае вы можете захотеть сохранить ширину в переменной, чтобы использовать ее позже, так как при добавлении видов в макет она может понадобиться.источник
Несмотря на то, что предлагаемое решение работает, оно может быть не лучшим решением для каждого случая, потому что на основе документации для
ViewTreeObserver.OnGlobalLayoutListener
это означает, что он вызывается много раз, и не всегда измеряется представление (для него определены высота и ширина)
Альтернативой является использование,
ViewTreeObserver.OnPreDrawListener
которое вызывается только тогда, когда представление готово к рисованию и имеет все свои измерения.источник
Вам лучше взглянуть на View жизненный цикл: http://developer.android.com/reference/android/view/View.html Как правило, вы не должны знать ширину и высоту наверняка, пока ваша активность не перейдет в состояние onResume.
источник
Вы можете использовать трансляцию, которая вызывается в OnResume ()
Например:
Вы не можете получить высоту представления в OnCreate (), onStart () или даже в onResume () по причине того, что kcoppock ответил
источник
Высота и ширина равны нулю, потому что представление не было создано к тому времени, когда вы запрашиваете его высоту и ширину. Одним из самых простых решений является
Этот метод хорош по сравнению с другими методами, поскольку он короткий и четкий.
источник
Простой ответ: Это сработало для меня без проблем. Кажется, ключ состоит в том, чтобы убедиться, что представление имеет фокус, прежде чем вы получите getHeight и т. Д. Сделайте это с помощью метода hasFocus (), а затем с помощью метода getHeight () в этом порядке. Требуется всего 3 строки кода.
ImageButton myImageButton1 =(ImageButton)findViewById(R.id.imageButton1);
myImageButton1.hasFocus();
int myButtonHeight = myImageButton1.getHeight();
Log.d("Button Height: ", ""+myButtonHeight );//Not required
Надеюсь, поможет.
источник
Используйте getMeasuredWidth () и getMeasuredHeight () для вашего представления.
Руководство разработчика: Просмотреть
источник
ИСПРАВЛЕНИЕ: Я обнаружил, что вышеуказанное решение ужасно. Особенно, когда ваш телефон работает медленно. И здесь я нашел другое решение: вычислить значение px элемента, включая поля и отступы: dp to px: https://stackoverflow.com/a/6327095/1982712
или измерения от .xml до px: https://stackoverflow.com/a/16276351/1982712
sp to px: https://stackoverflow.com/a/9219417/1982712 (отменить решение)
или размеры в px: https://stackoverflow.com/a/16276351/1982712
и это все.
источник