Я также столкнулся с этой проблемой, но в моем случае у меня была страница, FragmentPagerAdapter
которая снабжала ViewPager
ее страницами. Проблема, с которой я столкнулся, заключалась в том, что onMeasure()
метод ViewPager
вызывался до того, как какой-либо из Fragments
них был создан (и поэтому не мог правильно определить размер).
После нескольких проб и ошибок я обнаружил, что finishUpdate()
метод FragmentPagerAdapter вызывается после Fragments
инициализации (из instantiateItem()
in FragmentPagerAdapter
), а также после / во время прокрутки страницы. Я сделал небольшой интерфейс:
public interface AdapterFinishUpdateCallbacks
{
void onFinishUpdate();
}
который я передаю в мой FragmentPagerAdapter
и называю:
@Override
public void finishUpdate(ViewGroup container)
{
super.finishUpdate(container);
if (this.listener != null)
{
this.listener.onFinishUpdate();
}
}
что в свою очередь позволяет мне обратиться setVariableHeight()
к моей CustomViewPager
реализации:
public void setVariableHeight()
{
// super.measure() calls finishUpdate() in adapter, so need this to stop infinite loop
if (!this.isSettingHeight)
{
this.isSettingHeight = true;
int maxChildHeight = 0;
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
for (int i = 0; i < getChildCount(); i++)
{
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED));
maxChildHeight = child.getMeasuredHeight() > maxChildHeight ? child.getMeasuredHeight() : maxChildHeight;
}
int height = maxChildHeight + getPaddingTop() + getPaddingBottom();
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.measure(widthMeasureSpec, heightMeasureSpec);
requestLayout();
this.isSettingHeight = false;
}
}
Я не уверен, что это лучший подход, хотел бы услышать комментарии, если вы думаете, что это хорошо / плохо / зло, но, похоже, в моей реализации это работает довольно хорошо :)
Надеюсь, это поможет кому-то там!
РЕДАКТИРОВАТЬ: я забыл добавить requestLayout()
после вызова super.measure()
(в противном случае это не перерисовать представление).
Я также забыл добавить отступы родителя до конечной высоты.
Я также прекратил сохранять исходные параметры MeasureSpec ширины / высоты в пользу создания нового по мере необходимости. Обновили код соответствующим образом.
Еще одна проблема, с которой я столкнулся, заключалась в том, что он не мог правильно ScrollView
определить размер в a и обнаружил, что виновник измерял ребенка MeasureSpec.EXACTLY
вместо MeasureSpec.UNSPECIFIED
. Обновлено, чтобы отразить это.
Все эти изменения были добавлены в код. Вы можете проверить историю, чтобы увидеть старые (неправильные) версии, если хотите.