También me encontré con este problema, pero en mi caso tenía una FragmentPagerAdapterque estaba suministrando ViewPagersus páginas. El problema que tuve fue que onMeasure()de la ViewPagerque se llamó antes de cualquiera de los Fragmentshubiese sido creado (y por lo tanto no podía tamaño sí correctamente).
Después de un poco de prueba y error, descubrí que el finishUpdate()método del FragmentPagerAdapter se llama después de Fragmentshaber sido inicializado (desde instantiateItem()adentro FragmentPagerAdapter), y también después / durante el desplazamiento de la página. Hice una pequeña interfaz:
public interface AdapterFinishUpdateCallbacks
{
void onFinishUpdate();
}
que paso a mi FragmentPagerAdaptery llamo:
@Override
public void finishUpdate(ViewGroup container)
{
super.finishUpdate(container);
if (this.listener != null)
{
this.listener.onFinishUpdate();
}
}
que a su vez me permite invocar setVariableHeight()mi CustomViewPagerimplementación:
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;
}
}
No estoy seguro de que sea el mejor enfoque, me encantarían los comentarios si crees que es bueno / malo / malo, pero parece estar funcionando bastante bien en mi implementación :)
Espero que esto ayude a alguien por ahí!
EDITAR: Olvidé agregar un requestLayout()después de llamar super.measure()(de lo contrario, no vuelve a dibujar la vista).
También olvidé agregar el relleno de los padres a la altura final.
También dejé de mantener el ancho / alto original MeasureSpecs a favor de crear uno nuevo según sea necesario. Han actualizado el código en consecuencia.
Otro problema que tuve fue que no se dimensionaba correctamente en una ScrollViewy descubrí que el culpable estaba midiendo al niño en MeasureSpec.EXACTLYlugar de hacerlo MeasureSpec.UNSPECIFIED. Actualizado para reflejar esto.
Todos estos cambios se han agregado al código. Puede consultar el historial para ver las versiones antiguas (incorrectas) si lo desea.