关于ScrollView嵌套ViewPager 嵌套 ListView 嵌套 WebView 大全

匿名 (未验证) 提交于 2019-12-03 00:27:02

这几天做一个页面,需要用到ScrollView嵌套ViewPager,而ViewPager(Fragment)中又有两个Fragment 分别包含ListView以及WebView,大概的层级是这样的:

这样布局就会导致Viewpager WebView ListView 三个控件都显示不出来,导致这样的原因是,在Measure流程的时候,不能测出这三个控件的宽高,导致这三个控件不能显示,说到Measure 大家应该都知道该怎么解决了吧,没错,就是重写这三个控件的onMeasure方法,我们先来看看重写的ViewPager,当然重写ViewPager的方法,网上也有很多,就是关于这个问题的。大家,也可以去看看别人的博客,下面贴代码:

public class AutofitHeightViewPager extends ViewPager {     private int current;     private int height = 0;     /**      * 保存position与对于的View      */     private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();      private boolean scrollble = true;      private static final String TAG = "AutofitHeightViewPager";      public AutofitHeightViewPager(Context context) {         super(context);     }      public AutofitHeightViewPager(Context context, AttributeSet attrs) {         super(context, attrs);     }       @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) {              RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();             if (layoutParams == null) {                 layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height);             } else {                 layoutParams.height = height;             }              Log.d(TAG, "resetHeight: "+height);              setLayoutParams(layoutParams);         }     }     /**      * 保存position与对于的View      */     public void setObjectForPosition(View view, int position)     {         mChildrenViews.put(position, view);     } 

说好重写onMeasure 方法,怎么还多了两个方法呢?
如果只重写onMeasure方法,看看onMeasure方法,你会发现,在方法中,为了所Fragment都能显示完全,只会选择最大值,来作为ViewPager的总高度,那么,高度较小的那个Fragment下方就会留出很多空白,这样非常不美观,最好的办法就是动态设置当前ViewPager的高度。下面我们看看多出来的方法,是用来干嘛的。

setObjectForPosition:将当前的Fragment传递到类开头声明的成员中,建议在初始化Fragment的时候调用一下这个方法,将Fragment存入到当前的自定义的ViewPager中,以便后面使用,Position是查找对应Fragment的Key。
resetHeight:传入当前ViewPager显示的页面下标,获取到当前的Fragment的实际高度,设置为当前ViewPager的高度,这个方法建议设置ViewPager的页面切换监听,来实现设置不同高度。

当然,光重写ViewPager是不行的,还需要将 ViewPager 中对应加载的控件的onMeasure都重写,

ListView:

public class AutoFitHeightListView extends ListView {     public AutoFitHeightListView(Context context) {         super(context);     }      public AutoFitHeightListView(Context context, AttributeSet attrs) {         super(context, attrs);     }      public AutoFitHeightListView(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);     }      @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);         super.onMeasure(widthMeasureSpec, mExpandSpec);     } }

WebView:

public class AutoFitHeightWebView extends WebView {      @SuppressLint("NewApi")     public NoScrollWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {         super(context, attrs, defStyleAttr, defStyleRes);     }      public NoScrollWebView(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);     }      public NoScrollWebView(Context context, AttributeSet attrs) {         super(context, attrs);     }      public NoScrollWebView(Context context) {         super(context);     }      @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);         super.onMeasure(widthMeasureSpec, mExpandSpec);     }  }

这两个就只要重写哦你Measure方法就可以了,到这就差不多了。

剩下的就是在项目中,把控件都换成自定义的控件就好了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!