Android 在ScrollView中的导航栏悬浮吸顶方法实现

效果图:

----------------------------------------------------------------------------

补充内容:

鉴于有些同学看不懂原文内容,在此补充一下。

特别强调,以上代码实现真的很简单。以下原理及步骤,按照步骤边看边思考:

一、页面布局组成:

1、首先,页面布局最外层采用线性垂直布局(LinearLayout)

2、头部标题栏,在最外层Linearlayout里面,标题栏需要获取本身高度来用于后面计算导航栏滚动位置,我代码中标题栏高度是固定的值

3、FrameLayout,并列放在标题栏下面

4、自定义scrollview,放在FrameLayout里面,自定义scrollview目的是监听本身的滚动参数,内部方法 onScrollChanged无法被外部引用,需要定义一个接口监听该方法参数

5、创建空的LinearLayout(怕下面会误导,这个占位就叫LinearLayout1),并列放在scrollview下面,不包含任何子控件,只用于占位,充当装导航栏的容器

6、在scrollview里面放个LinearLayout。

7、最后,在scrollview包裹的LinearLayout里面放一个LinearLayout(这个占位就叫LinearLayout2)并在这个(LinearLayout2)里面装入导航栏。LinearLayout2是充当装导航栏的容器。LinearLayout2上面和下面就是并列的内容布局了。

看到这里,应该就知道怎么做了吧。

二、Activity类  Java代码部分,也按照步骤来吧:

 这里不放代码,只讲原理,代码请参考原文部分。

1、监听scrollview的滑动

2、获取标题栏高度

3、在监听scrollview的滑动方法里面,计算导航栏距离屏幕顶部的距离

4、比较标题栏高度和导航栏距离屏幕顶部的距离

5、导航栏距离屏幕顶部的距离小于标题栏高度,将导航栏动态添加到占位容器LinearLayout1中6、导航栏距离屏幕顶部的距离大于标题栏高度时再将导航栏动态添加回到占位容器LinearLayout2

至此,结束,代码请参考原文部分。不懂的地方就百度吧。

补充demo代码:Android 在ScrollView中的导航栏悬浮吸顶方法实现(demo)_萧萧风的博客-CSDN博客

----------------------------------------------------------------------------

----------------------------------------------------------------------------原文:

效果分析:

往上滑动scrollview当

导航栏距屏幕顶部的距离小于等于标题栏的高度时 悬浮,即上滑到紧贴标题栏时 悬浮。

反之:

(导航栏原来的位置)下滑到距离大于标题栏的高度时将悬浮的导航栏放回原来的位置。

实现步骤:

1、首先是布局实现,在内容布局(标题下面的容器)中,最外层使用FrameLayout包裹住ScrollView(自定义ScrollView,写一个接口监听它的onScrollChanged方法)控件和一个空的LinearLayout控件(用于动态将ScrollView控件中的导航栏添加到里面)。

xml布局,大致酱紫,不重要的view都已省略,重点看注释,看注释,看注释:

<LinearLayout 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"
    android:orientation="vertical">
 <!--此处省略标题栏-->

 <!--内容布局最外层使用FrameLayout-->
  <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

           <!--下面是自定义scrollview-->
            <MyScrollView
            android:id="@+id/myScrollview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fillViewport="true"
            android:focusable="true">

               <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:orientation="vertical">
                 <!--此处省略头部view-->

                  <!--下面LinearLayout用于包裹导航栏控件-->
                   <LinearLayout
                    android:id="@+id/line_add_navigation_fixation"
                    android:layout_width="match_parent"
                    android:layout_height="填写固定的导航栏高度"
                    android:background="@color/white"
                    android:orientation="vertical">

                   <!--此处省略导航栏view-->
                    
                </LinearLayout>
               
                    <ViewPager
                    android:id="@+id/viewPage_device"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />

               </LinearLayout>

            </MyScrollView>
                  <!--下面LinearLayout用于占位-->
           <LinearLayout
            android:id="@+id/line_add_navigation_suspension"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:orientation="vertical">
                    
            </LinearLayout>
       </FrameLayout>

 </LinearLayout>

 2、然后是java代码

主要代码,重点还是看注释:

//scrollview的滑动监听  
  @Override
    public void onScrollChanged(MyScrollView ceshimy, int scrollX, int scrollY, int oldl, int oldt) {
        int[] location = new int[2];
        lineAddNavigationFixation.getLocationOnScreen(location);
 //lineAddNavigationFixation是包裹导航栏的LinearLayout

        int y = location[1];//导航栏距屏幕顶部的距离,会随着scrollview的滑动而改变
        if (y <= titleView.getHeight()) {//导航栏距屏幕顶部的距离小于等于标题栏的高度时 悬浮,即上滑到紧贴标题栏时 悬浮
            addNavigationSuspension();
        } else {//反之下滑到距离大于标题栏的高度时放回原来的位置
            addNavigationFixation();
        }

    }

  private void addNavigationSuspension() {//添加悬浮
 //lineAddNavigationSuspension是布局中的占位LinearLayout
        if (lineAddNavigationSuspension.getChildCount() == 0) {
           
            if (navigationDevice.getParent() != null)
                ((ViewGroup) navigationDevice.getParent()).removeView(navigationDevice);

            lineAddNavigationSuspension.addView(navigationDevice);
        }
    }

    private void addNavigationFixation() {//悬浮固定到原位置
        if (lineAddNavigationFixation.getChildCount() == 0) {
            //  L.e("---" + "固定");
            if (navigationDevice.getParent() != null)
                ((ViewGroup) navigationDevice.getParent()).removeView(navigationDevice);

            lineAddNavigationFixation.addView(navigationDevice);
        }
    }

ok,逻辑代码这么点,是不是so简单。

实现原理:

简单概括就是:

布局中,固定一个位置紧靠着标题栏的Linearlayout空控件,和在导航栏控件的外层包裹一个固定高度的Linearlayout控件。监听scrollview的滑动位置,做出相应操作动态将导航栏控件添加到某一个Linearlayout控件中。

结束。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萧萧风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值