温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android实现选中突出背景效果的底部导航栏功能

发布时间:2020-11-02 15:43:01 来源:亿速云 阅读:804 作者:Leah 栏目:开发技术

本篇文章给大家分享的是有关Android实现选中突出背景效果的底部导航栏功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

贝塞尔曲线是Path 里面的api,而Path 是可以连续画线的,

那么就好实现了,前面直接设置起点 

mPath.moveTo(0, 0);//起始点

然后中间是直接的直接调用 

mPath.lineTo(x,y);

需要突出就调用二阶贝塞尔曲线

mPath.quadTo(x1,y1,x2,y2);

果然可行,画出来效果是这样

Android实现选中突出背景效果的底部导航栏功能

不错 实现第一步了,但是仔细观察发现 人家下面是有白色背景的,突出的地方也要白色背景,怎么搞呢!

又去查了下Path 和Paint Api 发现 有一种方法可以实现这样的效果

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

画笔要设置成 这种风格的

mPath.lineTo(getWidth(), getHeight()); mPath.lineTo(0, getHeight()); mPath.close(); //封闭path路径

Path路径全部占满

然后就可以实现效果了

记得把画笔颜色设置成白色的哦

mPaint.setColor(Color.WHITE);

果然可行!

一顿布局出来的效果是这样的

Android实现选中突出背景效果的底部导航栏功能

好丑啊

不过已经迈出成功的第一步了,继续完善

首先这个突出的弧度好像跟UI不一样呀

又是一顿分析,发现突出的时候是有三个曲线组成的

那么就会有三个控制点

Android实现选中突出背景效果的底部导航栏功能

画的有点丑 凑合看

a b c 都是控制点
1-2 是第一段
2-3 是第二段
3-4 是第三段

三段对应三个控制点

所以我们要画四阶贝塞尔曲线

结果Path里面最多支持三阶。。。。。。。

没办法只能拆开成三个了

根据图可以算出 a b c 控制点和1 2 3 4点的位置

手机屏幕长度假设为w

现在底部是三个模块那么一个模块所占的距离 i=w/3

那么 1就是起始点 

b是i的中心点

4是i点

Y方向的最高度为 -y(注意是负数哦)

假如按照三个贝塞尔曲线的长度都一样那么各个点的位置分别是

1(0,0) 2(i/2/2,y/2) 3(i-i/2/2,y/2) 4(i,0) a(i/2/2/2,y/2/2/2) b(i/2,y) c(i-i/2/2/2,y/2/2/2)

那么我们把这些点套入贝塞尔曲线里面

//第一条贝塞尔曲线 a 2 mPath.quadTo(i / 2 / 2 / 2 , -(minHeight / 2 / 2 / 2), i / 2 / 2 , -(minHeight / 2)); //第二条贝塞尔曲线 b 3 mPath.quadTo(i / 2 + i , -minHeight, i - i / 2 / 2 + i , -(minHeight / 2)); //第三条贝塞尔曲线 c 4 mPath.quadTo(i - i / 2 / 2 / 2 , -(minHeight / 2 / 2 / 2), i + i * (count - 1), 0);

然后这是第一模块的,后面模块的计算就是加上几段i值

模块从1开始,现在是有3个模块数值就是 (1 2 3) 

//第一条贝塞尔曲线 a 2 mPath.quadTo(i / 2 / 2 / 2 + i * (count - 1), -(minHeight / 2 / 2 / 2), i / 2 / 2 + i * (count - 1) + minHeight / 5, -(minHeight / 2)); //第二条贝塞尔曲线 b 3 mPath.quadTo(i / 2 + i * (count - 1), -minHeight, i - i / 2 / 2 + i * (count - 1) - minHeight / 5, -(minHeight / 2)); //第三条贝塞尔曲线 c 4 mPath.quadTo(i - i / 2 / 2 / 2 + i * (count - 1), -(minHeight / 2 / 2 / 2), i + i * (count - 1), 0);

这样就可以直接设置 count值 然后重新绘制就完成点击切换了

全部代码

package com.wavewave.mylibrary; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import androidx.annotation.Nullable; /** * @author wavewave * @CreateDate: 2020/10/28 10:23 AM * @Description: 底部导航 选中突出View 背景 * @Version: 1.0 */ public class BottomOutNavigation extends View { private Paint mPaint; //起始点 private int beginY = dip2px(0); //边距 private int margin = dip2px(0); /** * 默认 突出最高点 Y */ private int minHeight = dip2px(40); //第几个从0开始 private int count = 1; /** * 默认3个 根据实际情况写 */ private int maxCount = 3; public static String TAG = "LineView"; private int height; private int width; private Path mPath; public BottomOutNavigation(Context context) { this(context, null); } public BottomOutNavigation(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public BottomOutNavigation(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPath = new Path(); mPaint = new Paint(); // mPaint.setStyle(Paint.Style.STROKE); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setColor(Color.WHITE); mPaint.setAntiAlias(true);//抗锯齿 //2、通过Resources获取 DisplayMetrics dm = getResources().getDisplayMetrics(); height = dm.heightPixels; width = dm.widthPixels; } /** * 设置选择 * * @param count */ public void setCount(int count) { this.count = count; invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int i = width / maxCount;//单个所占大小 Log.d(TAG, "i:" + i); mPath.reset(); mPath.moveTo(0, 0);//起始点 mPath.lineTo(margin + i * (count - 1), 0); // //第一条贝塞尔曲线 a 2 mPath.quadTo(i / 2 / 2 / 2 + i * (count - 1), -(minHeight / 2 / 2 / 2), i / 2 / 2 + i * (count - 1) + minHeight / 5, -(minHeight / 2)); //第二条贝塞尔曲线 b 3 mPath.quadTo(i / 2 + i * (count - 1), -minHeight, i - i / 2 / 2 + i * (count - 1) - minHeight / 5, -(minHeight / 2)); //第三条贝塞尔曲线 c 4 mPath.quadTo(i - i / 2 / 2 / 2 + i * (count - 1), -(minHeight / 2 / 2 / 2), i + i * (count - 1), 0); mPath.lineTo(width, beginY); mPath.lineTo(getWidth(), getHeight()); mPath.lineTo(0, getHeight()); mPath.close(); //封闭path路径 canvas.drawPath(mPath, mPaint); } /** * 根据屏幕的分辨率从 dp 的单位 转成为 px(像素) */ public int dip2px(float dpValue) { final float scale = getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }

以上就是Android实现选中突出背景效果的底部导航栏功能,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI