Как указано выше в hariseldon78, ни одно из этих решений не решает проблему REAL, которая определяет высоту строки элемента списка ДО того, как она будет отображена. У меня возникла та же проблема: я хотел масштабировать некоторые изображения до высоты строк моего элемента ListView и не хотел масштабировать их до фиксированного значения. Если из-за темы текст в других частях макета строки менялся по высоте, я хотел, чтобы высота была такой, чтобы в моей подпрограмме getView адаптера я мог соответствующим образом изменить размер карты. Я боролся с проблемой, что getHeight и все измеренные высоты сообщают ноль, пока строка не будет отрисована. Для того, чтобы я увидел правильные высоты позже, было слишком поздно.
Мое решение состоит в том, чтобы создать onLayoutChangedListener () в первый раз через getView и только для строки 0. Слушатель сработает, как только завершится выполнение getView для первой позиции (0), и тогда параметр "bottom" скажет вам высоту ряда. Я записываю это в пользовательскую переменную класса адаптера, чтобы она была доступна в качестве параметра высоты без необходимости извлекать высоту снова.
Слушатель отменяет регистрацию как часть своего выполнения. Это обеспечивает правильную высоту для строк 1-N, но не для нулевой строки. Для нулевого ряда я сделал что-то действительно противное. У меня был вызов прослушивателя getView AGAIN для строки 0 после установки другой переменной класса адаптера для управления рекурсией. Во второй раз, когда getView (0) запустится, он не настроит слушателя и найдет допустимый параметр для высоты, с которым будет работать, и все хорошо.
Код приведен ниже - не нужно рассказывать мне, как это УЖАСНО - если андроид не должен был уследить, чтобы сказать, насколько велик мой вид, когда я заканчиваю заполнять вид на основе рендеринга Пармс на поверхность Мне бы не пришлось заниматься этим безобразием, но это работает. Извините, если форматирование кода ужасное ...
int mHeight = 0;
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
... usual boiler plate stuff
// JUST THE FIRST TIME
if (position == 0 && mHeight == 0) {
final View ref = convertView;
convertView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
ref.removeOnLayoutChangeListener(this);
mHeight = bottom;
firstTime = false;
// NOW LETS REGET THE FIRST VIEW WITH THE HEIGHT CORRECT
int visiblePosition = getListView().getFirstVisiblePosition();
View view = getListView().getChildAt(0 - visiblePosition);
getListAdapter().getView(0, view, getListView());
// RECURSION LOL
}
});
}
// Configure the view for this row
....
// HOW BIG IS THE VIEW?
// NOW IF NOT FIRSTTIME (MHEIGHT != 0)
if (mHeight != 0) {
// DO OUR IMAGE SETUP HERE CAUSE mHeight is RIGHT!
Log.d(TAG, "mHeight=" + mHeight);
}
return convertView;
}