我已经按照
this和
that的答案,我也找到了
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(); } }