Android: ViewPager с динамической высотой в ScrollView

У меня есть ScrollView, в котором находится ViewPager, который содержит фрагменты динамической высоты. Поскольку ScrollView и ViewPager не сочетаются друг с другом из-за обработки прокрутки, я использовал одно из настраиваемых решений здесь. Но в настоящее время я получаю действительно ненормальные результаты. Первый фрагмент в ViewPager всегда получает высоту 0. Также иногда фрагменты не показывают свой контент, но когда я прокручиваю назад и вперед и возвращаюсь к этому фрагменту, содержимое может отображаться.

Некоторый код для просмотра:

Пользовательский ViewPager:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by Narayan Acharya on 12/07/2016.
 */
public class DynamicHeightWrappingViewPager extends ViewPager {
    private View mCurrentView;

    public DynamicHeightWrappingViewPager(Context context) {
        super(context);
    }

    public DynamicHeightWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mCurrentView == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }

        int height = 0;
        mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = mCurrentView.getMeasuredHeight();
        if (h > height) height = h;
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        Log.d("ViewPager Measure", h + ":" + heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void measureCurrentView(View currentView) {
        mCurrentView = currentView;
        requestLayout();
    }
}

Пользовательский ScrollView:

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * Created by Narayan Acharya on 12/07/2016.
 */
public class ChildrenHeightAdaptingScrollView extends ScrollView {
    private GestureDetector mGestureDetector;

    public ChildrenHeightAdaptingScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new YScrollDetector());
        setFadingEdgeLength(0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev)
                && mGestureDetector.onTouchEvent(ev);
    }

    // Return false if we're scrolling in the x direction
    class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            return (Math.abs(distanceY) > Math.abs(distanceX));
        }
    }
}

PagerAdapter:

import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v13.app.FragmentPagerAdapter;
import android.util.Log;
import android.view.ViewGroup;

/.. Some more project specific imports here../
/**
 * Created by Narayan Acharya on 22/06/2016.
 */
public class EventsPagerAdapter extends FragmentPagerAdapter {

    private Event event;
    private int PAGE_COUNT = 2;
    private int mCurrentPosition = -1;
    private String tabTitles[] = new String[]{"INFO", "FAQs"};

    public EventsPagerAdapter(FragmentManager fm, Event event) {
        super(fm);
        this.event = event;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return EventInfoFragment.getInstance(event);
            case 1:
                return EventFAQsFragment.getInstance(event);
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return PAGE_COUNT;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return tabTitles[position];
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        if (position != mCurrentPosition) {
            Fragment fragment = (Fragment) object;
            DynamicHeightWrappingViewPager pager = (DynamicHeightWrappingViewPager) container;
            if (fragment != null && fragment.getView() != null) {
                mCurrentPosition = position;
                pager.measureCurrentView(fragment.getView());
                Log.d("Requested Measure for", position + " " + fragment.getClass().getSimpleName());
            }
        }
    }
}

Согласно моим наблюдениям, единственное различие, которое я смог обнаружить в коде из ссылки, упомянутой выше, и той, которую я использую, заключается в том, что ссылка использует FragmentPagerAdapter из библиотеки поддержки v4, в то время как я использую ее из v13 (Can not измените это на v4, из-за некоторых других ограничений). Каковы основные различия между двумя версиями библиотеки поддержки, как я ее использую?

Ответ 1

Это может показаться действительно глупым, и я не уверен, почему это работает точно! Если кто-нибудь знает, почему, пожалуйста, ответьте.

Проблема с распадом ViewPager заключалась в том, что она содержала только WebView в каждом Fragment. Я много трудился, пытаясь найти решения и записывая больше пользовательских ViewPagers и ScrollViews. Когда я собирался сдаться, я обернул WebView в LinearLayout, а Fragment в позиции 0 не рухнул. Теперь он работает плавно.

Итак, если кто-то получает пустые страницы при попытке этого или подобных решений, попробуйте обернуть его в LinearLayout или что-то в этом роде.

Надеюсь, это поможет кому-то!