• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android NestedScrollView 嵌套ViewPager不显示和出现空白部分 解决方法

武飞扬头像
宋勤東
帮助1

Android NestedScrollView 嵌套ViewPager不显示和出现空白部分 解决方法

问题分析:
NestedScrollView里面只能有一个ViewGroup,也就是只允许有一个子节点(允许一个父子节点包含多个子子节点)的存在。

  1. 如果你的NestedScrollView包含了多个子节点就会报错,一般来说,都会在所有子节点的最外层嵌套一个LinearLayout或者其他你业务场景的布局。
  2. viewpager为什么不能显示内容,
    无论你是这样设置宽高
android:layout_width="match_parent"
       android:layout_height="match_parent"

还是这样设置宽高,都无法显示

  android:layout_width="match_parent"
        android:layout_height="wrap_content"

但是你给高度设置具体的数值时“android:layout_height=“100dp””,才可以显示内容,但是如果你的ViewPager里面的Fragment 拥有一个RecyclerView或者webView的时候,固定的数值明显不能从根本上解决问题。

原因:
NestedScrollView 计算高度先于 ViewPager 渲染呈现前,所以 ViewPager 的高度才会一直是0,除非你自己给了固定高度
问题解决一:viewpager不显示内容
在NestedScrollView 控件属性中加入
android:fillViewport=“true”

局限是:低于Android 9 以下版本开发的时候

问题解决二:viewpager无法上下滑动
给ViewPager 重写一遍测量,重新给测量高度;
在每次测完后将测量得到的高度保存下来,
下次ViewPager 再切换回来就可以直接设置高度
public class myViewPager extends ViewPager {
    public myViewPager(@NonNull Context context) {
        super(context);
    }

    public myViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        for (int i = 0; i < getChildCount(); i  ) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height)
                height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}


学新通
问题解决三:viewpager不显示内容或者有空白(解决方案一)

还是重写viewpager重新计算高度

public class AutoHeightViewPager extends ViewPager {
    private int current;
    private int height = 0;
    /**
     * 保存position与对于的View(保存view对应的索引)
     */
    private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();

    private boolean scrollble = true;

    public AutoHeightViewPager(@NonNull Context context) {
        super(context);
    }

    public AutoHeightViewPager(@NonNull Context context, @Nullable 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();
        }
        if (mChildrenViews.size() != 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    /**
     * 重新设置高度
     *
     * @param current
     */
    public void resetHeight(int current) {
        this.current = current;
        if (mChildrenViews.size() > current) {
            FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
            if (layoutParams == null) {
                layoutParams = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
            } else {
                layoutParams.height = height;
                layoutParams.height = 0;
            }
            setLayoutParams(layoutParams);
        }
    }
    /**
     * 保存position与对于的View(保存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;
    }

}

学新通

使用方法:
第一步: Activity中



    val tabList = arrayListOf<String>()
    val fragments= arrayListOf<HomeFragment>()
	//数据源
        data.forEachIndexed { index, it ->
            tabList.add(it.tabName.toString())
            fragments.add( HomeFragment.newInstance(it.tabUrl.toString()))
        }

        viewPager?.adapter = HomeFragmentPagerAdapter(childFragmentManager,fragments,tabList)

        viewPager.offscreenPageLimit = fragments.size
        tabLayout.setupWithViewPager(viewPager)
        tabLayout.addOnTabSelectedListener(object :OnTabSelectedListener{
            override fun onTabSelected(tab: TabLayout.Tab?) {
                val position:Int = tab?.position ?: 0
                viewPager.resetHeight(position)
                viewPager.currentItem = position
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {

            }

            override fun onTabReselected(tab: TabLayout.Tab?) {

            }

        })

        viewPager.resetHeight(0)
        viewPager.currentItem = 0
学新通

第二步: HomeFragment中

viewPager?.setObjectForPosition(linearLayout, position)

但是这种方法有一个问题,在ViewPager中的第一个Fragment高度始终为0
经过多次尝试和实践,总结出另一种解方案

问题解决三:viewpager不显示内容或者有空白 (解决方案二)

使用协调者布局CoordinatorLayout

第一步:在Activity的布局中使用


    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@ id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/color_gray">


            <com.谷歌.android.material.appbar.AppBarLayout
                android:id="@ id/appBarLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/color_white"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways">

                <com.谷歌.android.material.appbar.CollapsingToolbarLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:contentScrim="?attr/colorPrimary"
                    app:expandedTitleMarginEnd="60dp"
                    app:expandedTitleMarginStart="50dp"
                    app:layout_scrollFlags="scroll|exitUntilCollapsed">

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

                        <com.youth.banner.Banner
                            android:id="@ id/banner"
                            android:layout_width="match_parent"
                            android:layout_height="@dimen/dp_130"
                            android:layout_marginStart="@dimen/dp_15"
                            android:layout_marginTop="@dimen/dp_15"
                            android:layout_marginEnd="@dimen/dp_15"
                            android:background="@drawable/ic_default_big_img"
                            banner:banner_indicator_normal_color="@drawable/oval_sost_fff_trans_1"
                            banner:banner_indicator_selected_color="@drawable/oval_so_white"
                            banner:banner_radius="10dp" />

                    </LinearLayout>

                </com.谷歌.android.material.appbar.CollapsingToolbarLayout>

                <FrameLayout
                    android:id="@ id/flTobView"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_90"
                    android:background="@color/color_white"
                    app:layout_collapseMode="pin">

                    <com.谷歌.android.material.tabs.TabLayout
                        android:id="@ id/tabLayout"
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/dp_48"
                        android:layout_gravity="bottom"
                        app:tabBackground="@color/color_white"
                        app:tabGravity="fill"
                        app:tabIndicator="@drawable/tab_indicator_main"
                        app:tabIndicatorColor="@color/color_main"
                        app:tabIndicatorFullWidth="false"
                        app:tabIndicatorHeight="@dimen/dp_5"
                        app:tabMaxWidth="0dp"
                        app:tabMode="auto"
                        app:tabRippleColor="#ffffff"
                        app:tabSelectedTextColor="@color/color_main"
                        app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
                        app:tabTextColor="@color/color_black"
                        tools:contentDescription="@string/app_name" />

                </FrameLayout>

            </com.谷歌.android.material.appbar.AppBarLayout>

            <androidx.viewpager.widget.ViewPager
                android:id="@ id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="com.谷歌.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />

        </androidx.coordinatorlayout.widget.CoordinatorLayout>
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
学新通

第二步:在ViewPager嵌套的Fragment的布局中使用

<androidx.core.widget.NestedScrollView android:id="@ id/linearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="com.谷歌.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <WebView
        android:id="@ id/webView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:isScrollContainer="true"
        android:scrollbars="none" />
</androidx.core.widget.NestedScrollView>

最终完美解决该问题
参考: NestedScrollView嵌套viewpager不显示内容的解决方案
Android ScrollView嵌套ViewPager不显示和出现空白部分 解决方法
NestedScrollView嵌套viewpager无法上下滑动Android ScrollView嵌套ViewPager不显示和出现空白部分 解决方法

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfagca
系列文章
更多 icon
同类精品
更多 icon
继续加载