You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义底部导航栏实现上滑隐藏下滑显示方案问询

实现自定义底部导航栏的滑动隐藏/显示效果(无第三方库)

嘿,我看了你用LinearLayout和RelativeLayout自定义的底部导航栏,要实现上滑隐藏、下滑显示的效果其实不难,咱们一步步来搞定它:

核心思路

监听页面内容区域的滚动方向,判断是上滑还是下滑,然后通过属性动画平滑地控制底部导航栏的显示与隐藏——上滑时让导航栏向下移出屏幕,下滑时再拉回原位置。


步骤1:准备工作(在MainActivity中)

首先获取底部导航栏的实例,并提前拿到它的高度,方便后续动画计算:

private RelativeLayout bottomToolbar;
private int bottomToolbarHeight;
// 记录上次滚动位置,避免频繁触发动画
private int lastScrollY = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    // 获取底部导航栏控件
    bottomToolbar = findViewById(R.id.bottom_toolbar);
    
    // 获取导航栏高度(需要等布局完成后才能拿到准确值)
    bottomToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            bottomToolbarHeight = bottomToolbar.getHeight();
            // 拿到高度后移除监听,避免重复回调
            bottomToolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
}

步骤2:监听内容区域的滚动事件

你的页面内容是放在MageNative_frame_container这个FrameLayout里的Fragment,所以需要在Fragment中的滚动控件(比如RecyclerView/ScrollView)添加滚动监听:

如果用的是RecyclerView:

// 在你的目标Fragment中
RecyclerView recyclerView = findViewById(R.id.your_recyclerview_id);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        // dy > 0 表示上滑,dy < 0 表示下滑
        // 加个阈值(比如20px)避免轻微滚动就触发动画
        if (dy > 20 && bottomToolbar.getVisibility() == View.VISIBLE) {
            // 调用MainActivity的隐藏方法
            ((MainActivity) getActivity()).hideBottomToolbar();
        } else if (dy < -20 && bottomToolbar.getVisibility() == View.GONE) {
            // 调用MainActivity的显示方法
            ((MainActivity) getActivity()).showBottomToolbar();
        }
        lastScrollY = recyclerView.computeVerticalScrollOffset();
    }
});

如果用的是ScrollView:

// 在你的目标Fragment中
ScrollView scrollView = findViewById(R.id.your_scrollview_id);
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
    @Override
    public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
        int dy = scrollY - oldScrollY;
        // 同样加阈值避免误触发
        if (dy > 20 && bottomToolbar.getVisibility() == View.VISIBLE) {
            ((MainActivity) getActivity()).hideBottomToolbar();
        } else if (dy < -20 && bottomToolbar.getVisibility() == View.GONE) {
            ((MainActivity) getActivity()).showBottomToolbar();
        }
        lastScrollY = scrollY;
    }
});

步骤3:实现平滑的显示/隐藏动画

在MainActivity中添加两个方法,用属性动画实现导航栏的平滑移动:

// 隐藏底部导航栏:向下移出屏幕
private void hideBottomToolbar() {
    bottomToolbar.animate()
            .translationY(bottomToolbarHeight) // 移动距离等于导航栏高度
            .setDuration(300) // 动画时长300ms
            .setInterpolator(new AccelerateInterpolator()) // 加速插值器,动画越来越快
            .withEndAction(new Runnable() {
                @Override
                public void run() {
                    bottomToolbar.setVisibility(View.GONE); // 动画结束后隐藏,避免占位置
                }
            });
}

// 显示底部导航栏:从下方移回原位置
private void showBottomToolbar() {
    bottomToolbar.setVisibility(View.VISIBLE); // 先设置可见,再执行动画
    bottomToolbar.animate()
            .translationY(0)
            .setDuration(300)
            .setInterpolator(new DecelerateInterpolator()); // 减速插值器,动画越来越慢,更自然
}

额外优化建议

  1. 统一管理监听逻辑:如果多个Fragment都需要这个效果,可以写一个BaseFragment,把滚动监听的逻辑放在里面,其他Fragment继承它即可,减少重复代码。
  2. 内容不足时不触发:可以判断滚动控件的总滚动范围,如果内容没有超过屏幕高度,就不执行隐藏逻辑。
  3. 避免动画重复触发:除了加滚动阈值,还可以通过lastScrollY判断滚动趋势,防止来回滚动时频繁触发动画。

内容的提问来源于stack exchange,提问作者Areeb Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:47:38