在安卓中的ScrollView中设置ViewPager的高度

11

我需要在ScrollView中展示一个ViewPager(一页幻灯片行中的图像和图像下方的文本)。我正在从网上下载图像和文本,并在幻灯片行中显示它们。我将ViewPager包装在ScrollView中,以支持横向模式。

 <com.xxx.myapp.android.ui.CustomScrollView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:fadingEdge="none"
    android:fillViewport="true"
    android:gravity="center">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"
        android:orientation="vertical" >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="800dp"
            android:layout_gravity="top"
            android:layout_marginTop="10dp" />  
    </LinearLayout>
</com.xxx.myapp.android.ui.CustomScrollView> 

这里是CustomScrollView。问题是如何根据子项高度设置视图分页器的高度,以便只能滚动屏幕直到视图分页器项目结束。如果我将视图分页器高度设置为wrapcontent,则ViewPager中不会显示任何内容。如果我设置一些800dp,那么我可以看到Pager项目,但屏幕上会出现不必要的滚动条。我不希望我的ScrollView在Pager子项高度之外滚动。请帮帮我。


不要给 View pager 设定固定高度。 - Piyush
你解决了吗?我也遇到了同样的问题。 - Bhavesh Hirpara
@Gayathri 请分享 com.xxx.myapp.android.ui.CustomScrollView 类的代码。 - Smit Patel
5个回答

24

为了固定viewpager的高度,我们可以自定义viewpager类。

public class WrapContentViewPager extends ViewPager {

private int mCurrentPagePosition = 0;

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

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
        View child = getChildAt(mCurrentPagePosition);
        if (child != null) {
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public void reMeasureCurrentPage(int position) {
    mCurrentPagePosition = position;
    requestLayout();
}
}

在viewpager的onPageSelected回调中,应该调用reMeasureCurrentPage方法,并且CustomScrollView是父视图。


1
我需要一个高度与当前显示的子项相同的ViewPager。 这是SOF上众多答案中的完美解决方案。 - Santhosh
完美!谢谢! - Madi
对我不起作用。 我在ViewPager内容中有一个GridView。 - John61590
对我起作用了,但在滚动到最后一个项目时调整ViewPager的高度。 - Muhammed Haris

9
mViewPager = new ViewPager(mContext) {
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

            View view = getChildAt(this.getCurrentItem());
            if (view != null) {
                view.measure(widthMeasureSpec, heightMeasureSpec);
            }
            setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view));
        }

        private int measureHeight(int measureSpec, View view) {
            int result = 0;
            int specMode = MeasureSpec.getMode(measureSpec);
            int specSize = MeasureSpec.getSize(measureSpec);

            if (specMode == MeasureSpec.EXACTLY) {
                result = specSize;
            } else {
                // set the height from the base view if available
                if (view != null) {
                    result = view.getMeasuredHeight();
                }
                if (specMode == MeasureSpec.AT_MOST) {
                    result = Math.min(result, specSize);
                }
            }
            return result;
        }
    };

6

尝试这种方法

<com.xxx.myapp.android.ui.CustomScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:fadingEdge="none"
    android:fillViewport="true"
    android:gravity="center">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:descendantFocusability="blocksDescendants"
        android:orientation="vertical" >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="top"
            android:layout_marginTop="10dp" />  
    </LinearLayout>
</com.xxx.myapp.android.ui.CustomScrollView> 

0

将您的分页行包装在CustomScrollView中,而不是将分页器包装在CustomScrollview中。并且不要像Piyush Gupath评论的那样固定Viewpager的高度。使用wrapcontent。


0

这是最好的且简单的解决方案:

1)在您的自定义ViewPager类内部 -

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    var heightMeasureSpec = heightMeasureSpec
    val mode = MeasureSpec.getMode(heightMeasureSpec)
    // Unspecified means that the ViewPager is in a ScrollView WRAP_CONTENT.
    // At Most means that the ViewPager is not in a ScrollView WRAP_CONTENT.
    if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
        // super has to be called in the beginning so the child views can be initialized.
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var height = 0
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            child.measure(
                widthMeasureSpec,
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
            )
            val h = child.measuredHeight
            if (h > height) height = h
        }
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
    }
    // super has to be called again so the new specs are treated as exact measurements
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}

2) 在将适配器设置到您的ViewPager时 -

val viewPagerAdapter = ViewPagerAdapter(fragmentList, supportFragmentManager)
view_pager.adapter = viewPagerAdapter
view_pager.measure(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT)`
view_pager.currentItem = 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接