Я також зіткнувся з цією проблемою, але в моєму випадку у мене виникло таке, FragmentPagerAdapter
що постачало ViewPager
його сторінки. Проблема, яку я мав, полягала в тому, onMeasure()
що ViewPager
виклик був викликаний до того, як Fragments
було створено будь-яке (і тому він не міг правильно розмістити себе).
Після невеликих проб і помилок я виявив, що finishUpdate()
метод FragmentPagerAdapter викликається після Fragments
ініціалізації (з instantiateItem()
в 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;
}
}
Я не впевнений, що це найкращий підхід, я хотів би коментувати, якщо ви вважаєте, що це добре / погано / зло, але, здається, він працює досить добре в моїй реалізації :)
Сподіваюся, це допомагає комусь там!
EDIT: Я забув додати requestLayout()
після виклику super.measure()
(інакше це не переробить представлення).
Я також забув додати батьківську підкладку до кінцевої висоти.
Я також відмовився зберігати оригінальну MeasureSpecs ширини / висоти на користь створення нової відповідної потреби. Оновили код відповідно.
Іншою проблемою у мене було те, що він не розмістив би себе правильно в ScrollView
і виявив, що винуватець заміряє дитину MeasureSpec.EXACTLY
замість MeasureSpec.UNSPECIFIED
. Оновлено, щоб відобразити це.
Ці зміни були додані до коду. Ви можете перевірити історію, щоб побачити старі (неправильні) версії, якщо хочете.