Android - 使用不同高度的子级更新ViewPager

时间:2015-03-11 03:02:11

标签: java android android-viewpager

我有一个没有片段(只是视图)的ViewPager。每个页面都包含一个元素列表,但列表的大小并不总是相同。

我尝试使用此代码设置ViewPager维度(扩展ViewPager,以便我可以覆盖此函数):

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

问题是它为每个页面设置了相同的高度。我需要每页的自定义高度,具体取决于列表的高度。

我还尝试在ViewPager上使用setOnPageChangeListener调用requestLayout()invalidate(),但大小保持不变。也许我做错了......

以下是一些可能有用的代码:

我的PagerAdapter的一部分:

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // Inflate a new layout from our resources
            View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_home_pager,
                    container, false);

            mContainerView = (ViewGroup) view.findViewById(R.id.news_container);
            reloadNews(position);

            // Add the newly created View to the ViewPager
            container.addView(view);

            // Return the View
            return view;
        }

我的XML布局的一部分:

        <ScrollView
            android:id="@+id/news_scrollview"
            android:layout_width="match_parent"
            android:layout_height="fill_parent">

            <com.ViewPagerWithHeight
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white"/>

        </ScrollView>

非常感谢帮助我,

2 个答案:

答案 0 :(得分:0)

ViewPager高度不能像您希望的那样每页变化。您可以尝试子类ViewPager来添加此功能,但处理不同大小的页面之间的可视转换将非常繁琐。另一种选择可能是在每次页面更改时重新测量ViewPager(但我希望转换看起来非常糟糕)。您需要设置页面更改侦听器,然后在ViewPager上调用requestLayout。您的ViewPager onMeasure只需要找到当前可见子项的高度,并将ViewPager高度设置为与此匹配。

除了:我没有看到你在任何地方呼叫setMeasuredDimension。在测量视图时,必须使用计算出的宽度和高度调用此方法,以通知视图测量的大小。目前,您在自定义super.onMeasure的末尾呼叫onMeasure,虽然有效,但仍表示ViewPager将始终使用“默认”宽度和高度进行衡量。在这种情况下,无论如何,这恰好匹配最大页面的高度。

有关详细信息,请参阅onMeasure的文档。特别是:

  

合同:重写此方法时,必须调用setMeasuredDimension(int,int)来存储此视图的测量宽度和高度。如果不这样做将触发由measure(int,int)抛出的IllegalStateException。调用超类'onMeasure(int,int)是一种有效的用途。

答案 1 :(得分:0)

我只是找到了能够完成这项工作的东西。

我将Scrollview移到了pageItem.xml里面,所以我可以设置页面大小(适用于所有页面),但如果列表足够长,仍然可以滚动。 ViewPager现在位于FrameLayout layout_height = fill_parent内。

页面大小是固定的,但是scrollview可以解决这个问题......

ViewPager(在我的片段中):

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:id="@+id/viewpagercontainer">

    <com.ViewPagerWithHeight
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"/>

</FrameLayout>

&#34; Page项目&#34; :

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/news_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:showDividers="middle"
        android:divider="?android:dividerHorizontal" />

</ScrollView>

onMeasure功能:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    heightMeasureSpec = MeasureSpec.makeMeasureSpec(containerHeight, MeasureSpec.EXACTLY);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

如何设置属性containerHeight(更多信息here):

final View pagerContainer = (View) mView.findViewById(R.id.viewpagercontainer);
pagerContainer.post(new Runnable() {
    @Override
    public void run() {
        mViewPager.setContainerHeight(pagerContainer.getMeasuredHeight());
    }
});