Natknąłem się również na ten problem, ale w moim przypadku miałem taki, FragmentPagerAdapterktóry dostarczał ViewPagerswoje strony. Problem, który miałem, polegał na tym, onMeasure()że ViewPagerzostał wywołany przed utworzeniem któregokolwiek z Fragmentsnich (i dlatego nie mógł się odpowiednio dopasować).
Po kilku próbach i błędach odkryłem, że finishUpdate()metoda FragmentPagerAdapter jest wywoływana po Fragmentszainicjowaniu (od instantiateItem()w FragmentPagerAdapter), a także po / podczas przewijania strony. Zrobiłem mały interfejs:
public interface AdapterFinishUpdateCallbacks
{
void onFinishUpdate();
}
które przechodzę do mojego FragmentPagerAdapteri wołam:
@Override
public void finishUpdate(ViewGroup container)
{
super.finishUpdate(container);
if (this.listener != null)
{
this.listener.onFinishUpdate();
}
}
co z kolei pozwala mi wezwać setVariableHeight()moją CustomViewPagerimplementację:
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;
}
}
Nie jestem pewien, czy to najlepsze podejście, chętnie komentuję, jeśli uważasz, że jest dobre / złe / złe, ale wydaje się, że działa całkiem dobrze w mojej realizacji :)
Mam nadzieję, że to pomoże komuś tam!
EDYCJA: Zapomniałem dodać requestLayout()po wywołaniu super.measure()(inaczej nie przerysuje widoku).
Zapomniałem również dodać podkładki rodzica do ostatecznej wysokości.
Porzuciłem również zachowanie oryginalnej szerokości / wysokości MeasureSpecs na korzyść stworzenia nowej w razie potrzeby. Zaktualizowałem odpowiednio kod.
Innym problemem, jaki miałem, było to, że nie zmieściłoby się ono prawidłowo w a ScrollViewi stwierdził, że sprawca mierzył dziecko MeasureSpec.EXACTLYzamiast MeasureSpec.UNSPECIFIED. Zaktualizowano, aby to odzwierciedlić.
Wszystkie zmiany zostały dodane do kodu. Możesz sprawdzić historię, aby zobaczyć stare (niepoprawne) wersje, jeśli chcesz.