Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom ViewPager inside ObservableScrollView not measuring Height Properly

I have a CustomViewPager inside an ObservableScrollView which looks like this:

enter image description here

It seems to measure the fragment but does not measure the height of the fragment which is off the screen. So I can't actually scroll up.

This is the code for the CustomViewPager:

public class CustomViewPager extends ViewPager {

private View view;

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

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

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;

    View tab = getChildAt(getCurrentItem());
    int width = getMeasuredWidth();
    int tabHeight = tab.getMeasuredHeight();

    if (wrapHeight) {
        // Keep the current measured width.
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
    }

    int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView());
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public int measureFragment(View view) {
    if (view == null)
        return 0;

    view.measure(0, 0);
    return view.getMeasuredHeight();
}

}

NOTE: If I add say + 1000 to heightMeasureSpec in super.onMeasure(widthMeasureSpec, heightMeasureSpec); then I can scroll the size of the fragment as well as any extra space. But obviously this is not a preferred solution.

Here is my XML file:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<LinearLayout
    android:id="@+id/infoBox"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="240dp">

    <!-- Code for other views -->

</LinearLayout>

<com.github.ksoichiro.android.observablescrollview.ObservableScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:scrollbars="none">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="266dp"
        android:orientation="vertical">

        <com.ui.customviewpager.CustomViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


    </LinearLayout>

</com.github.ksoichiro.android.observablescrollview.ObservableScrollView>

What seems to be the issue here? It seems like I am not the only one with this issue.

I implemented some of this design from this link here

like image 607
AndyRoid Avatar asked Jan 08 '23 17:01

AndyRoid


2 Answers

ScrollView child should not have margin for the scrollView to display properly. It seems that the margin is not taken into account when the scrollView measure its child.

Try removing margin of LinearLayout (you can use padding to reproduce the effect).

like image 122
Gyome Avatar answered Jan 30 '23 22:01

Gyome


Why dont you use ObservableScrollView inside the fragment and put the viewpager inside a TouchInterceptionFrameLayout (from the same lib), then set setTouchInterceptionViewGroup of the ObservableScrollView to be the one containing your viewpager and do the logic on the TouchInterceptionListener in your activity to either move it up and down with with animation in order to mimic a smooth scrolling effect.

I hope that is that your are looking for to achieve and hopefully it will help you.

Ps: See the guy example app and source (Link), it is a bit complex but im sure you will find something.

like image 21
murielK Avatar answered Jan 30 '23 23:01

murielK