一、前言
界面构成是CoordinatorLayout + AppBarLayout(TabLaout) + ScrollView,其中ScrollView包含ViewPager,ViewPager中包含Fragment(ListView)的复杂布局。
参考:Android ScrollView嵌套ViewPager不显示和出现空白部分 解决方法
二、使用
使用的是第二种方法,自定义ViewPager
public class ViewPagerForScrollView extends ViewPager{
private int current;
private int height = 0;
/**
* 保存position与对于的View
*/
private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
private boolean scrollble = true;
public ViewPagerForScrollView(Context context) {
super(context);
}
public ViewPagerForScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mChildrenViews.size() > current) {
View child = mChildrenViews.get(current);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height = child.getMeasuredHeight();
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void resetHeight(int current) {
this.current = current;
if (mChildrenViews.size() > current) {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
if (layoutParams == null) {
layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
} else {
layoutParams.height = height;
}
setLayoutParams(layoutParams);
}
}
/**
* 保存position与对于的View
*/
public void setObjectForPosition(View view, int position)
{
mChildrenViews.put(position, view);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!scrollble) {
return true;
}
return super.onTouchEvent(ev);
}
public boolean isScrollble() {
return scrollble;
}
public void setScrollble(boolean scrollble) {
this.scrollble = scrollble;
}
}
布局
<ScrollView
android:id="@+id/sv_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ViewPagerForScrollView
android:id="@+id/home_list_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
Fragment中
@SuppressLint("ValidFragment")
public HomTestFragment(ExpandViewPager viewPager){
this.viewPager = viewPager;
}
在onCreateView中设置位置
viewPager.setObjectForPosition(rootView, 0);
Activity中设置界面切换监听
viewPagerHome.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
viewPagerHome.resetHeight(position);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
三、总结
比起参考的解决方法,修改后 ViewPager 可以滚动。另外,控件不显示问题是要重新计算高度,滑动冲突则需分配触摸事件。