动态高度不起作用的Viewpager(始终使用第一个片段的高度)

Bla*_*ama 7 android android-fragments android-viewpager

我已经按照这个那个答案,我也找到了这个链接.

我使用这些资源进行试验和错误.现在我的自定义ViewPager成功测量了它的内容,但只显示了第一个.仅供参考,我ViewPager持有一些复杂的观点,比如ExpendableListView- 这就是为什么这些资源中的代码都没有完美运行,我需要自己修改代码.

我有4个片段(内容),所以我使用 pager.setOffscreenPageLimit(3);

这是我的习惯ViewPager:

public class CustomViewPager extends ViewPager{

    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;

        final View tab = getChildAt(0);
        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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的CustomPagerTabStrip:

int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
android.view.ViewGroup.LayoutParams params =  getLayoutParams();
params.height = getMeasuredHeight();
Run Code Online (Sandbox Code Playgroud)

这是我的XML:

        <RelativeLayout
            android:id="@+id/relativePager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <com.xxx.yyy.util.CustomViewPager
                android:id="@+id/detailPager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <com.xxx.yyy.util.CustomPagerTabStrip
                    android:id="@+id/detailTab"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#161C28"
                    android:textColor="#FFFFFF" />
            </com.xxx.yyy.util.CustomViewPager>

        </RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

示例案例:

如果第一个片段的高度为100px,那么所有其他片段将保持100px.因此,如果第二个片段的高度为130px,则将其切割为100px.

当我尝试调试时,onMeasureon my CustomViewPager总是在Activity创建时调用4次,但所有这些只读取第一个片段.该onMeasure 从来没有得到后再次调用,甚至当我改变(左滑动/右)从一个片段等.

请帮帮我,我花了很多时间让这个东西工作.只要问我是否需要更多信息,感谢您的时间.

Ren*_*K N 15

嗨Blaze发现有些东西用完了,以下解决方案对我有用.

它包括自定义滚动视图和自定义视图寻呼机.目的自定义视图寻呼机是根据其子高度动态计算高度,其高度设置为最初包装内容,滚动视图的目的是处理触摸事件,如果用户垂直滚动屏幕则不会通过触摸甚至滚动,因此用户可以滚动页面.

自定义滚动视图

public class CustomScrollView extends ScrollView {

private GestureDetector mGestureDetector;

public CustomScrollView(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 SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY) {
        return (Math.abs(distanceY) > Math.abs(distanceX));
    }
}
}
Run Code Online (Sandbox Code Playgroud)

自定义视图寻呼机

public class CustomPager extends ViewPager{

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

public CustomPager (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;

    final View tab = getChildAt(0);
    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();
}
}
Run Code Online (Sandbox Code Playgroud)

布局文件

<com.example.demo2.activity.widget.CustomScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

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

    <TextView
        style="@style/text"
        android:text="Text 1" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 2" />


        <com.example.demo2.activity.widget.CustomPager
          android:id="@+id/myViewPager"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 4" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 5" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 6" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 7" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 8" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 9" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 10" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

活动

public class MainActivity extends FragmentActivity {



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    MyPagerAdapter pageAdapter = new MyPagerAdapter(getSupportFragmentManager());
    ViewPager pager = (ViewPager)findViewById(R.id.myViewPager);
    pager.setAdapter(pageAdapter);

}



}
Run Code Online (Sandbox Code Playgroud)

片段适配器

不同高度的碎片被添加到viewpager,FragmentBlue,Green等只是片段用于添加到viewpager你可以使用自己的片段,有一点需要记住的是他们的外部布局应该是相同的在我的情况下我使用的衬垫布局为所有

public class MyPagerAdapter extends FragmentPagerAdapter {

private List<Fragment> fragments;

public MyPagerAdapter(FragmentManager fm) {
    super(fm);
    this.fragments = new ArrayList<Fragment>();
    fragments.add(new FragmentBlue());
    fragments.add(new FragmentGreen());
    fragments.add(new FragmentPink());
    fragments.add(new FragmentRed());
}

@Override
public Fragment getItem(int position) {
    return fragments.get(position);
}

@Override
public int getCount() {
    return fragments.size();
}
}
Run Code Online (Sandbox Code Playgroud)