仿马蜂窝TabLayout 波纹滑动菜单导航栏

2024-06-01 16:32

本文主要是介绍仿马蜂窝TabLayout 波纹滑动菜单导航栏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先看一下马蜂窝的样式
在这里插入图片描述
我刚看到觉得下面的样式好神奇,自己就像动手做一做。

由于数学方面我不是很精通,我的实现方式没有复杂的公式计算,而是通过绘制+覆盖的形式。

自己写一个TabLayout过于麻烦,这里就借用了MaterialDesign 的TabLayout改动了其中的draw的代码;

这里绘制路径主要用的是贝塞尔曲线不了解的可以先去网上搜下用法
1.首先设置Paint绘制线条

int lineWidth = 8;
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(lineWidth);

2.TabLayout中又一个方法可以计算出每个tab的边界坐标

private void calculateTabViewContentBounds(@NonNull TabView tabView, @NonNull RectF contentBounds) {int tabViewContentWidth = tabView.getContentWidth();int minIndicatorWidth = (int) ViewUtils.dpToPx(getContext(), MIN_INDICATOR_WIDTH);if (tabViewContentWidth < minIndicatorWidth) {tabViewContentWidth = minIndicatorWidth;}int tabViewCenter = (tabView.getLeft() + tabView.getRight()) / 2;int contentLeftBounds = tabViewCenter - (tabViewContentWidth / 2);int contentRightBounds = tabViewCenter + (tabViewContentWidth / 2);contentBounds.set(contentLeftBounds, 0, contentRightBounds, 0);}

3.从起点开始绘制所有Tab的底部曲线

//设置本文的宽度默认为100,后期可以自己根据情况进行设置
int total = 100;
for (int i = 0; i < getTabCount(); i++) {View tabView = getChildAt(i);calculateTabViewContentBounds((TabView) tabView, tabViewContentBounds);int left = (int) tabViewContentBounds.left;int right = (int) tabViewContentBounds.right;//底部曲线起点、终点距Tab边界的距离smDim = (right - left - total) / 2;//绘制第一个tab的曲线if (i == 0) {//移动到曲线绘制起点mPath.moveTo(left + smDim, startY);//开始规划路径mPath.rQuadTo(total / 2, indicatorHeight / 2, total, 0);} else {int cx = smDim + (left - lastRight) / 2;//绘制两个tab之间的曲线mPath.rQuadTo(cx, -indicatorHeight + lineWidth, smDim + lastsmDim + (left - lastRight), 0);//绘制tab下面的曲线mPath.rQuadTo(total / 2, indicatorHeight / 2, total, 0);}//记录上次的边界坐标lastRight = right;lastsmDim = smDim;}
//开始绘制路径                                canvas.drawPath(mPath, paint);

这样整个tab下面的曲线就完成了,如下图所示:
在这里插入图片描述
4.开始绘制中遮罩层,覆盖曲线只留下当前位置tab的总宽度

                blockPaint.setStyle(Paint.Style.FILL);blockPaint.setColor(Color.parseColor("#f8f8f8"));int dimen = (indicatorRight - indicatorLeft - total) / 2;canvas.drawRect(0, indicatorTop, indicatorLeft + dimen, indicatorBottom, blockPaint);canvas.drawRect(indicatorRight - dimen, indicatorTop, getWidth(), indicatorBottom, blockPaint);

根据tab的移动 动态绘制遮罩层就实现了曲线移动的视觉
最终实现结果如下图所示:
在这里插入图片描述
这里有一个问题就是当两个相邻tab的宽度相差比较大的时候曲线在某一点拐点比较生硬。

当然如果数学功底比较好的,可以根据坐标计算出贝塞尔曲线在某一点的坐标值,这样可能会解决上面的问题。

如果有更好的方法还请多多指教;

Demo 地址

这篇关于仿马蜂窝TabLayout 波纹滑动菜单导航栏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1021526

相关文章

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

Windows如何添加右键新建菜单

Windows如何添加右键新建菜单 文章目录 Windows如何添加右键新建菜单实验环境缘起以新建`.md`文件为例第一步第二步第三步 总结 实验环境 Windows7 缘起 因为我习惯用 Markdown 格式写文本,每次新建一个.txt后都要手动修改为.md,真的麻烦。如何在右键新建菜单中添加.md选项呢? 网上有很多方法,这些方法我都尝试了,要么太麻烦,要么不凑效

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

【leetcode详解】考试的最大困扰度(滑动窗口典例)

实战总结: sum += answerKey[right] == c; 经典操作,将判断语句转化为0, 1接收来计数//大问题分解: 对'T'还是'F'做修改, 传参为c//滑动窗口: 遍历, 维护left& right指向 及 c的个数, 更新不知从何下手写代码时:考虑先写好第一次的,然后以此为基础补充代码以适后续情况 题面: 解题感受: 思路总体好想, 实现略有挑战。 思路分析:

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口)

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口) 题目描述 给定一个字符串 blocks,其中每个字符代表一个颜色块,可以是 ‘W’(白色)或 ‘B’(黑色)。你需要找到一个至少包含 k 个连续黑色块的子串。每次操作可以将一个白色块变成黑色块。你的任务是找到至少出现一次连续 k 个黑色块的最少操作次数。 和该题目类似:【每日一题】LeetCode 202

【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)

现在的新版AppWizard已经比较好用,用户可以轻松的创建各种项目常规界面。 比如早期创建一个支持滑动的主界面框架,并且可以跳转各种子界面,仅仅界面布局和各种图片格式转换都要花不少时间,而现在使用AppWizard,可以说轻轻松松,毫不费力。 用户唯一要做的就是根据自己的芯片性能做一定的速度优化。 视频: https://www.bilibili.com/video/BV17Rp3eLE

Flutter-listview的item左右滑动,删除item

import 'package:flutter/material.dart';//列表左右滑动删除void main() =>runApp(MaterialApp(home: HomePage(),));class HomePage extends StatelessWidget {final List<String> items = List.generate(20, (index) =>

如何在Qt的widget上右键显示菜单

如何在Qt的widget上右键显示菜单 今天早上一来,我老大叫我在widget上点击右键加上一个菜单,并相应其响应的功能,因为我成刚接触Qt,所以看了下QtGUI编程这本书,做出来,记录下来,说不定哪天还用得上啊! 废话不多说,直接上代码: 方法一: m_text = QTextCodec::codecForLocale(); ui->tableWidget->addAction(ne

java AWT PopupMenu(右键菜单)

右键菜单使用PopupMenu对象表示,创建步骤如下: (1)创建PopupMenu的实例。 (2)创建多个MenuItem的多个实例,依次将这些实例加入到PopupMenu中。 (3)将PopupMenu加入到目标组件中。 (4)为需要出现上下文菜单的组件编写鼠标监听器,当用户释放鼠标右键时弹出右键菜单。 package javaAWT;import java.awt.BorderLa