Eu também tive esse problema, mas no meu caso eu tinha um FragmentPagerAdapterque estava fornecendo as ViewPagerpáginas. O problema que tive foi onMeasure()o de ViewPagerchamado antes de qualquer um Fragmentsdeles ter sido criado (e, portanto, não era possível dimensionar-se corretamente).
Após algumas tentativas e erros, descobri que o finishUpdate()método do FragmentPagerAdapter é chamado após a Fragmentsinicialização (a partir de instantiateItem()no FragmentPagerAdapter) e também após / durante a rolagem da página. Eu fiz uma pequena interface:
public interface AdapterFinishUpdateCallbacks
{
void onFinishUpdate();
}
que eu passo na minha FragmentPagerAdaptere chamo:
@Override
public void finishUpdate(ViewGroup container)
{
super.finishUpdate(container);
if (this.listener != null)
{
this.listener.onFinishUpdate();
}
}
o que, por sua vez, me permite chamar setVariableHeight()minha CustomViewPagerimplementação:
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;
}
}
Não tenho certeza de que é a melhor abordagem, gostaria de comentar se você acha que é bom / ruim / mau, mas parece estar funcionando muito bem na minha implementação :)
Espero que isto seja útil a alguém!
EDIT: esqueci de adicionar um requestLayout()depois de chamar super.measure()(caso contrário, não redesenhar a exibição).
Também esqueci de adicionar o preenchimento dos pais à altura final.
Também deixei cair mantendo o MeasureSpecs de largura / altura original em favor da criação de um novo, conforme necessário. Atualizou o código de acordo.
Outro problema que tive foi que ele não se dimensionaria corretamente em um ScrollViewe descobriu que o culpado estava medindo a criança em MeasureSpec.EXACTLYvez de MeasureSpec.UNSPECIFIED. Atualizado para refletir isso.
Todas essas alterações foram adicionadas ao código. Você pode verificar o histórico para ver as versões antigas (incorretas), se desejar.