android – 动态高度不起作用的Viewpager(总是使用第一个片段的高度)

前端之家收集整理的这篇文章主要介绍了android – 动态高度不起作用的Viewpager(总是使用第一个片段的高度)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经按照 thisthat的答案,我也找到了 this链接.

我用这些资源做试验和错误.现在,我的自定义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();
    }
}

这是我的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();

这是我的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>

示例案例:

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

当我尝试调试时,我的CustomViewPager上的onMeasure在创建Activity时总是调用4次,但是所有这些都只读取了第一个片段.在那之后,即使我从一个片段改变(向左/向右滑动)到另一个片段,onMeasure也不会再被调用.

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

解决方法

嗨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));
    }
}
}

自定义视图寻呼机

public class CustomPager extends ViewPager{

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

public CustomPager (Context 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,MeasureSpec.AT_MOST);

    super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}

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

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

布局文件

<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>

活动

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);

}



}

片段适配器

不同高度的碎片被添加到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();
}
}
原文链接:https://www.f2er.com/android/317574.html

猜你在找的Android相关文章