android 中间凹背景_Android开发仿百度地图的凹陷BottomNavigationView
释放双眼,带上耳机,听听看~!
百度的:
71529789c6c948803e1075c2c7e00809.jpg
我的:
e9347423eb2031228af77ad63d7b01d7.jpg
使用
首先需要在attrs中申明两个属性
anchor_fab: 用来指定凹陷下去的 View ,一般都为 FloatingActionButton
shadow_length:用来指定高度(阴影大小)
cornerRadius:用来指定拐角处的平滑半径大小
导入源码(请直接copy)
源码采用Kotlin,有需要可以直接转为Java,转换方法自行百度
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.annotation.*
import com.example.rubbishcommunity.R
import com.google.android.material.bottomnavigation.BottomNavigationView
class GapBottomNavigationView : BottomNavigationView {
private var fabId = 0 //凹陷View的id
private var centerRadius: Float = 0.toFloat() //中间凹陷的半径
private var cornerRadius = 12f //拐角处的圆滑大小(越大越平滑)
private var shadowLength = 6f //阴影大小
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
background = GradientDrawable().apply { setColor(Color.TRANSPARENT) }
val ta = context.obtainStyledAttributes(attrs, R.styleable.GapBottomNavigationView)
fabId = ta.getResourceId(R.styleable.GapBottomNavigationView_anchor_fab, 0)
shadowLength = ta.getFloat(R.styleable.GapBottomNavigationView_shadow_length, 6.toFloat())
cornerRadius = ta.getFloat(R.styleable.GapBottomNavigationView_corner_radius, 12.toFloat())
ta.recycle()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//测量时才能拿到凹陷的View
val fab = (parent as ViewGroup).findViewById(fabId)
centerRadius = fab.width / 2.toFloat() + cornerRadius
invalidate()
}
@SuppressLint("DrawAllocation")
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val paint = Paint()
val path = Path()
//左边的半圆
val rectL = RectF(
shadowLength,
shadowLength,
height.toFloat() + shadowLength,
height.toFloat() - shadowLength
)
path.arcTo(rectL, 90.toFloat(), 180.toFloat(), false)
path.lineTo(width / 2 - centerRadius - cornerRadius, shadowLength)
//左边转角处
path.quadTo(
width / 2 - centerRadius,
shadowLength,
width / 2 - centerRadius,
cornerRadius + shadowLength
)
//中间凹陷的半圆
val rectCenter = RectF(
width / 2 - centerRadius,
cornerRadius + shadowLength - centerRadius,
width / 2 + centerRadius,
cornerRadius + centerRadius + shadowLength
)
path.arcTo(rectCenter, 180.toFloat(), (-180).toFloat(), false)
//利用贝塞尔曲线画中间凹陷(非半圆)
/* path.quadTo(
width.toFloat() / 2,
centerRadius.toFloat(),
width / 2 + centerRadius - cornerRadius - cornerRadius / sqrt(2.toFloat()),
cornerRadius / sqrt(2.toFloat())
)*/
//右边转角处
path.quadTo(
width / 2 + centerRadius,
shadowLength,
width / 2 + centerRadius + cornerRadius,
shadowLength
)
path.lineTo((width - shadowLength - height / 2), shadowLength)
//右边的半圆
val rectR = RectF(width.toFloat() -shadowLength - height, shadowLength, width.toFloat() - shadowLength, height.toFloat()-shadowLength)
path.arcTo(rectR, 270.toFloat(), 180.toFloat(), false)
//最后的直线
path.moveTo((width -shadowLength - height / 2), height.toFloat()-shadowLength)
path.lineTo(height / 2.toFloat() +shadowLength, height.toFloat() - shadowLength)
path.close()
//关闭硬件加速才能有阴影效果
setLayerType(LAYER_TYPE_SOFTWARE, paint)
//按背景色填充背景
paint.apply {
style = Paint.Style.FILL
color = backgroundTintList?.defaultColor ?: Color.BLACK
maskFilter = null
isAntiAlias = true
//添加阴影
setShadowLayer(shadowLength, 0.toFloat(), 0.toFloat(), Color.LTGRAY)
}
canvas.drawPath(path, paint)
}
}
建议:结合我的代码并利用 paint(画笔) 随意更改为你想要的形状
在 MainActivity 中使用
Menu :
xmlns:app="http://schemas.android.com/apk/res-auto">
android:id="@+id/navigation_home"
android:icon="@drawable/nav_selector_home"
android:title="首页"
app:showAsAction="always" />
android:id="@+id/navigation_find"
android:icon="@drawable/nav_selector_find"
android:title="发现"
app:showAsAction="always" />
android:id="@+id/navigation_null"
android:enabled="false"
android:checked="false"
android:checkable="false"
android:icon="@null"
android:title="@null" />
android:id="@+id/navigation_message"
android:icon="@drawable/nav_selector_message"
android:title="消息"
app:showAsAction="always" />
android:id="@+id/navigation_mine"
android:icon="@drawable/nav_selector_mine"
android:title="我的"
app:showAsAction="always" />
XML :
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/btn_send_mqtt_smg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:clickable="true"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="@+id/maincontainer"
app:layout_constraintEnd_toEndOf="@+id/maincontainer"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/icon_email" />
android:id="@+id/maincontainer"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
android:id="@+id/bottomnavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="16dp"
android:padding="8dp"
android:backgroundTint="@color/white"
app:labelVisibilityMode="labeled"
app:cornerRadius="12dp"
app:anchor_fab="@id/fab_add"
app:shadow_length="12"
app:elevation="5dp"
app:itemBackground="@null"
app:itemIconTint="@color/black"
app:itemTextColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/navigation"
tools:targetApi="lollipop" />
android:id="@+id/fab_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="36dp"
android:backgroundTint="@color/colorWhite"
android:elevation="2dp"
android:src="https://www.jianshu.com/p/8cd6add34f19/@android:drawable/ic_input_add"
android:tint="@color/black"
app:borderWidth="0dp"
app:fabSize="normal"
app:layout_constraintBottom_toBottomOf="@+id/bottomnavigation"
app:layout_constraintEnd_toEndOf="@+id/bottomnavigation"
app:layout_constraintStart_toStartOf="@+id/bottomnavigation"
app:rippleColor="@color/colorAccent" />
我的效果就是这样咯
093143d5ebb666338bc164a6bd339da5.jpg
喜欢不要忘了点赞关注~~
android 中间凹背景_Android开发仿百度地图的凹陷BottomNavigationView相关推荐
- android 中间凹背景_Android 华为凹口屏适配小结
Android8.0 以后[凹口屏]得到迅速发展,目前已有了挖孔屏/水滴屏/刘海屏等各式各样的屏幕,究其根本依旧是[凹口屏],单华为一个品牌就涵盖了基本所有类型,而对于屏幕适配也是不可逃避的问题.和尚 ...
- android 中间凹背景_Android实现边缘凹凸的View
转载 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开始 ...
- Android 高仿百度地图的LBS服务——离线地图篇 Part 2 (v 3.1.1)
一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/41492031 这一篇blog写的真心不容易,我只想说我这种菜鸟去高仿百度 ...
- Android开发之百度地图定位打卡
Android开发之百度地图定位打卡 一.效果图 二.下载百度地图SDK 三.代码实现 1.布局文件(activity_main) 2.布局文件(activity_map) 3.在res文件夹下新建m ...
- Android开发之百度地图定位
Android开发之百度地图定位 一.效果图 二.下载百度地图SDK 1.打开[百度地图](https://lbsyun.baidu.com/index.php?title=%E9%A6%96%E9% ...
- 移动开发之百度地图导航及定位
一.获取密钥 在百度地图开发中,选择开发文档中的安卓地图SDK,并且点击获取密钥 在获取密钥的过程中,我们选择安卓开发,并且勾选好自己所需的服务之后,最重要的一步是获取SAH1码,这个码的获取流程较为 ...
- iOS开发之百度地图的简单集成——标注POI检索
iOS开发之百度地图的简单集成--标注&POI检索 .h文件 // Created by XK_Recollection on 16/6/15. // Copyright © 2016年 GN ...
- html5 百度地图api文档,开发指南--百度地图JavaScript API大众版.doc
开发指南--百度地图JavaScriptAPI大众版开发指南--百度地图JavaScriptAPI大众版 简介 JavaScript API大众版 JavaScript API功能介绍 百度地图Jav ...
- Android开发-基于百度地图API开发仿滴滴出行APP界面的实现
前 言 近年来,由于移动互联网快速的发展以及基于移动设备的APP的普及,移动互联网改变了人们的生活方式.从线上的电子支付到线下的出行,移动互联网是当今社会人们生活不可或缺的一部分,而线下出行的网约车的 ...
最新文章
- mac OneNote恢复历史记录
- flutter 自定义tab导航-顶部导航-底部导航
- nyoj 47 江 河问题 【贪婪】
- linux与开发板串口通信
- 见识决定眼界,关注这些让你变得博学且有趣
- Spring集成:轻量级集成方法
- 程序员被公司辞退12天,前领导要求回公司讲清楚代码,你们知道什么结果吗?
- Maximum Flow(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E)
- python print_Python print()
- python中run函数作用_python3多线程中如何改写run()函数?
- MFC对COM接口编写的支持分析
- Cadence Orcad Capture CIS原理图数据库的基本使用方法与技巧图文教程
- MonkeyTest小结
- 开源Java商城项目Javashop的部署过程
- 在线编辑Word——插入图片、图形
- Linux网络管理之ss命令– 显示活动套接字信息
- 【科创人独家】军哥手记程军:我的2020,先打个60分吧
- python For 循环 三种遍历方式
- 工作中遇到的问题汇总
- 如何定义一个高逼格的原生JS插件
热门文章
- Unity 分帧加载和分块加载
- laravel 清空表 truncate()
- output.topk()函数解读
- 删除根目录文件方法,解决报错EEXIST: file already exists
- find_new_reaper
- connectionStrings
- 移动计费系统学习(五)
- C语言字符串转ASCII、ASCII转字符串、字符串转数组、sprintf、toascii、类型强转、strtol、atoi
- 个人微信管理工具有哪些功能
- SpringSecurity - 基于 Servlet 的应用程序