Android 滑动标题导航栏_android上滑动合并标题栏-程序员宅基地

技术标签: 开源项目  标题导航  实用功能  Android导航  


我的视频课程:《FFmpeg打造Android万能音频播放器》


        现在Android应用开发中因为功能比较多所以都喜欢用viewpager+fragment的方式加入更多的页面,而每每使用这种模式,标题栏导航也是必不可少的,因此又会重复写很多导航菜单的代码,程序猿都是很懒的,都想写少量的代码就把功能实现了,更何况这都是写重复的代码,不辞辛劳的程序猿就成了CV战士了哈哈。我也是很懒的,不想每次都重复写那些没用的代码,所以就把标题导航栏这块功能封装成了一个自定义的控件,使用起来就三两句代码搞定,是不是听着很爽 反正我是觉得爽了。废话不多说,先上示例图片,所谓有图有真相:

综合类型:


1、第一种类型(只有滑动导航条):


2、第二种类型(滑动导航条有背景色)


3、第三种类型(滑动导航条有边距)


4、第四种类型(选中标题栏文字变大)


5、第五中类型(标题栏直接具有分隔条)


以上这些效果的实现代码只有下面几句(核心语句,去除初始化和布局代码):

navitationLayout.setViewPager(this, titles, viewPager, R.color.color_333333, R.color.color_2581ff, 16, 16, 0, 12, true, R.color.color_333333, 1f, 15f, 15f);
        navitationLayout.setBgLine(this, 1, R.color.colorAccent);
        navitationLayout.setNavLine(this, 3, R.color.colorPrimary, 0);


2、实现思路:

通过我们的需求不难发现,第一要生成标题栏的每个标题(TextView),然而标题又是横向排列的,所以自然就想到了我们的线性布局(LinearLayout),通过代码动态添加标题栏到LinearLayout中;最基本的就实现了,然后再看需求,我们还需要再底部添加导航条,因为导航条在底部,然后还具有背景色,所以我们用相对布局(RelativeLayout)来布局是比较好的,这样基本框架就可以了(父布局是相对布局,里面添加包含标题栏的线性布局,再在底部添加导航条背景布局,再在导航条背景上面添加导航条)。剩下的就是颜色,长款等细节问题的处理了。

3、功能逻辑代码

(1):标题栏

private void setTitles(Context context, String[] titles, final boolean smoothScroll)
    {
        this.textViews = new TextView[titles.length];
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT);
        params.weight = 1;
        params.gravity = Gravity.CENTER;
        // 循环,根据标题栏动态生成TextView来显示标题,每个标题栏的宽度比例为1:1,其中的内容居中。
        for(int i = 0; i < titles.length; i++)
        {
            final int index = i;
            TextView textView = new TextView(context);
            textView.setText(titles[i]);
            textView.setGravity(Gravity.CENTER);
            textViews[i] = textView;
            textViews[i].setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    viewPager.setCurrentItem(index, smoothScroll);
                    if(onTitleClickListener != null)
                    {
                        onTitleClickListener.onTitleClick(v);
                    }
                }
            });
            titleLayout.addView(textView, params);
        }
    }
用代码根据导航标题数量动态添加标题控件,并为每个标题添加点击事件。

(2):设置导航条背景

/**
     * 设置导航背景色
     * @param context
     * @param height
     * @param color
     */
    public void setBgLine(Context context, int height, int color)
    {
        height = dip2px(context,height);
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, height);
        bgLine = new View(context);
        bgLine.setLayoutParams(layoutParams);
        bgLine.setBackgroundColor(context.getResources().getColor(color));

        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, height);
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        addView(bgLine, lp);
    }

也是用代码为导航条添加背景view。

(3):添加导航条

/**
     * 设置导航条颜色
     * @param context
     * @param height
     * @param color
     * @param currentPosition
     */
    public void setNavLine(Activity context, int height, int color, int currentPosition)
    {
        if(textViews != null)
        {
            navWidth = getScreenWidth(context) / textViews.length;
        }
        height = dip2px(context,height);
        System.out.println("width:" + navWidth);

        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, height);
        navLine = new View(context);
        navLine.setLayoutParams(layoutParams);
        navLine.setBackgroundColor(context.getResources().getColor(color));

        LayoutParams lp = new LayoutParams(navWidth, height);
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        addView(navLine, lp);
        moveBar(navLine, navWidth, widOffset, currentPosition);
    }
根据标题的数量计算导航条的宽度,然后设置导航条颜色和边距。

(4):移动导航条功能

private void moveBar(View bar, int width, float percent, int position) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) bar.getLayoutParams();
        int marginleft = (position) * width + (int) (width * percent);
        lp.width = width - widOffset * 2;
        lp.setMargins(marginleft + widOffset, 0, widOffset, 0);
        bar.requestLayout();
    }
这个是结合viewpager的滑动事件的功能,根据滑动来定位导航条的位置。

(5)调用方法的设置

/**
     *
     * @param context 上下文
     * @param titles 标题栏
     * @param viewPager
     * @param unselectedcolor 未选中字体颜色
     * @param setectedcolor 选中字体颜色
     * @param txtUnselectedSize 未选中字体大小
     * @param txtSelectedSize 选中字体大小
     * @param currentPosition 当前viewpager的位置
     * @param widOffset 导航条的边距
     * @param smoothScroll 滑动类型
     */
    public void setViewPager(final Context context, String[] titles, ViewPager viewPager, final int unselectedcolor, final int setectedcolor, int txtUnselectedSize, final int txtSelectedSize, final int currentPosition, int widOffset, boolean smoothScroll)
    {
        this.viewPager = viewPager;
        this.txtUnselectedColor = unselectedcolor;
        this.txtSelectedColor = setectedcolor;
        this.txtUnselectedSize = txtUnselectedSize;
        this.txtSelectedSize = txtSelectedSize;
        this.widOffset = dip2px(context, widOffset);

        viewPager.setCurrentItem(currentPosition);
        setTitles(context, titles, smoothScroll);
        setUnselectedTxtColor(context, unselectedcolor, txtUnselectedSize);
        setSelectedTxtColor(context, setectedcolor, txtSelectedSize, currentPosition);
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                moveBar(navLine, navWidth, positionOffset, position);
                if(onNaPageChangeListener != null)
                {
                    onNaPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
                }
            }

            @Override
            public void onPageSelected(int position) {
                setSelectedTxtColor(context, setectedcolor, txtSelectedSize, position);
                if(onNaPageChangeListener != null)
                {
                    onNaPageChangeListener.onPageSelected(position);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if(onNaPageChangeListener != null)
                {
                    onNaPageChangeListener.onPageScrollStateChanged(state);
                }
            }
        });
    }
这个方法就是设置各种颜色、大小和边距的方法,并且把viewpager的pagechange回调给使用者调用。


核心代码就是这样的了,其他两种类型类似,这里就不多说了,可以看源码哦。

完整项目源码下载地址:

1、CSDN:NavigationBar

2、Github:NavigationBar

欢迎各位使用和start










版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ywl5320/article/details/51866799

智能推荐

彩色成像的基础和应用 原理 Principles(一)_彩色成像意义-程序员宅基地

文章浏览阅读149次。彩色成像的基础和应用 目录_彩色成像意义

DolphinScheduler on k8s 云原生部署实践_dolphinscheduler 云服务-程序员宅基地

文章浏览阅读1.2k次,点赞16次,收藏32次。1. DolphinScheduler 的高效云原生部署模式,比原始部署模式节省了95%以上的人力资源和工作时间,提升了部署效率和成本效益。2. 通过集成 GitOps 技术,我们提升了 DolphinScheduler 的 DevOps 管理能力,改善了软件交付效率和安全审计能力。3. 通过集成新的云原生技术,我们为 DolphinScheduler 增加了水平扩展、健康探测和滚动部署等功能,提升了其灵活性和适应性。4. 将 Prometheus 等可观测性技术整合到基础设施和服务网格中,显著提升了_dolphinscheduler 云服务

深度学习调参大法-学习率动态调整_图像识别中optim.adam(net.parameters(), lr=0.0002)里面的学习率-程序员宅基地

文章浏览阅读1.7k次,点赞4次,收藏11次。optim.StepLR,optim.MultiStepLR,optim.LambdaLR,optim.ExponentialLR,optim.CosineAnnealingLR,optim.ReduceLROnPlateau_图像识别中optim.adam(net.parameters(), lr=0.0002)里面的学习率如何设置能提高

CentOS7.5安装svn_centos7.5安装svn服务端-程序员宅基地

文章浏览阅读148次。CentOS7,svn_centos7.5安装svn服务端

oppo r9plus 无限制重启前的日志。_oppo手机重启日志-程序员宅基地

文章浏览阅读4.2k次。几个无意义网站访问dm.wo.com.cn/www.heytapmobi.comdata.ads.heytapmobi.com/09-10 14:49:06.325 13607-13607/? W/activity_lifecycle: com.heytap.cdo.client.ui.activity.MainTabPageActivity@3a5fe0 stop09-10 14:49:06.335 13607-13607/? D/Tinker.DefaultAppLike: onTr..._oppo手机重启日志

基于SpringBoot+Vue的母婴商城系统设计实现(源码+lw+部署文档+讲解等)-程序员宅基地

文章浏览阅读174次。博主介绍:全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐Java精品实战案例《500套》微信小程序项目精品案例《500套》文末获取源码+数据库。

随便推点

algorithm头文件下的常用函数_algorithm的那个取值-程序员宅基地

文章浏览阅读213次。//头文件#include<algorithm>max();min();abs();swap();//可以交换结构体reverse();//reverse(a,a+n)注意取值[);将数组进行反转可以操作结构体fill();//fill(a,a+n,num);sort();..._algorithm的那个取值

基于SpringBoot的宠物领养系统-程序员宅基地

文章浏览阅读964次,点赞20次,收藏23次。基于SpringBoot的宠物领养系统,java项目。eclipse和idea都能打开运行。推荐环境配置:eclipse/idea jdk1.8 maven mysql前端技术:vue,Ajax,Json后端技术:SpringBoot,MyBatis本系统共分为两个角色:管理员和用户。主要功能有:提供远程部署、代码讲解等服务更多精品项目,请查看主页。

【数据结构】:二叉树的递归遍历_遍历rnl的n是什么-程序员宅基地

文章浏览阅读952次。二叉树的遍历(递归)二叉树的遍历:是指沿着某条搜索路线,依次对树中每个节点做一次且仅做一次访问。N:代表根结点L:代表根结点的左子树R:代表根结点的右子树正在上传…重新上传取消NLR:先序遍历,又称作前序遍历,访问顺序为:根结点-->根的左子树-->根的右子树转存失败重新上传取消LNR:中序遍历,访问顺序为:根的左子树-->根结点-->根的右子树转存失败重新上传取消LRN:后序遍历,访问顺序为:根的左子树-->根的右子树-->根结点_遍历rnl的n是什么

Ant Design Pro(5)-5.网络请求_ant design pro request-程序员宅基地

文章浏览阅读2.6k次。它基于 axios 和 ahooks 的Request 提供了一套统一的网络请求和错误处理方案。_ant design pro request

DST 和 DCT的区别_dct dst-程序员宅基地

文章浏览阅读1k次。主要是由于帧内预测利用周围已经编码块的边缘像素,因此距离预测像素越远,预测残差越大。DST中的基函数比DCT能够很好的适应这一特征,将能量更好的集中在左上角:DST公式:DCT公式:举例4x4原始矩阵:Cos变换矩阵:Sin变换矩阵:..._dct dst

基于51单片机的模拟量输入输出通道实验_51单片机模拟通道程序-程序员宅基地

文章浏览阅读1.1k次,点赞18次,收藏23次。1、了解A/D、D/A转换的基本原理。2、了解A/D转换芯片ADC0809、D/A转换芯片DAC0832的性能及编程方法。3、掌握过程通道中A/D转换与D/A转换与计算机的接口方法。4、了解计算机如何进行数据采集及输出控制。计算机 1台;缔造者系统 1套:CPU挂箱、8031CPU模块;万用表 1块;示波器 1台。利用实验台上的ADC0809做A/D转换器,实验箱上的电位器提供模拟电压信号输入,编制程序,将模拟量转换成数字量,用数码管显示模拟量转换的结果。1、实验电路:如图1图1。_51单片机模拟通道程序

推荐文章

热门文章

相关标签