Android实现弧形菜单效果
发布时间 - 2026-01-11 00:27:06 点击率:次前言:公司需求,自己写的一个弧形菜单!

效果:
开发环境:AndroidStudio2.2.1+gradle-2.14.1
涉及知识:1.自定义控件,2.事件分发等
部分代码:
public class HomePageMenuLayout extends ViewGroup {
private Context context;
// 菜单项的文本
private String[] mItemTexts = null;
private int StatusHeight;//状态栏高度
public HomePageMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
StatusHeight = ScreenUtils.getStatusHeight(context);
}
/**
* 设置布局的宽高,并策略menu item宽高
*/
int resWidth = 0;
int resHeight = 0;
int mRadius = 0;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//布局宽高尺寸设置为屏幕尺寸
//设置该布局的大小
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
/**
* 根据传入的参数,分别获取测量模式和测量值
*/
int width = MeasureSpec.getSize(widthMeasureSpec);
resHeight = MeasureSpec.getSize(heightMeasureSpec);
resWidth = MeasureSpec.getSize(widthMeasureSpec);
// 获得半径
mRadius = (int) (resHeight / 2 - 2 * StatusHeight);
//设置item尺寸
int childSize = (int) (mRadius * 1 / 2);
// menu item测量模式--精确模式
int childMode = MeasureSpec.EXACTLY;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// 计算menu item的尺寸;以及和设置好的模式,去对item进行测量
int makeMeasureSpec = -1;
makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize, childMode);
child.measure(makeMeasureSpec, makeMeasureSpec);
}
}
/**
* item布局的角度
*/
private int[] widthall = null;
/**
* 设置Item的位置:第一个参数1:该参数指出当前ViewGroup的尺寸或者位置是否发生了改变
* 2.当期绘图光标横坐标位置
* 3.当前绘图光标纵坐标位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left, top;
int cWidth = (int) (mRadius * 1 / 2);
final int childCount = getChildCount();
// 计算,中心点到menu item中心的距离
float tmp = mRadius - cWidth / 2;
// 遍历去设置menuitem的位置
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
left = (int) (mRadius * Math.cos(Math.toRadians(widthall[i]))) - 65;
top = (int) (mRadius - (resHeight / 2 - 2 * StatusHeight) * Math.sin(Math.toRadians(widthall[i])) - StatusHeight);
child.layout(left, top, left + cWidth, top + cWidth);
}
}
public interface OnMenuItemClickListener {
void itemClick(View view, int pos);
}
public void setOnMenuItemClickListener(
OnMenuItemClickListener mOnMenuItemClickListener) {
this.mOnMenuItemClickListener = mOnMenuItemClickListener;
}
// 菜单的个数
private int mMenuItemCount;
/**
* 设置菜单条目的图标和文本
*/
public void setMenuItemIconsAndTexts(String[] mItemTexts) {
this.mItemTexts = mItemTexts;
this.mMenuItemCount = mItemTexts.length;
resultAngle();
addMenuItems();
}
private void resultAngle() {
switch (this.mMenuItemCount) {
case 3:
widthall = Constants.ITEM3;
break;
case 4:
widthall = Constants.ITEM4;
break;
case 5:
widthall = Constants.ITEM5;
break;
case 6:
widthall = Constants.ITEM6;
break;
case 7:
widthall = Constants.ITEM7;
break;
case 8:
widthall = Constants.ITEM8;
break;
case 9:
widthall = Constants.ITEM9;
break;
case 10:
widthall = Constants.ITEM10;
break;
default:
break;
}
}
/**
* 设置菜单条目的图标和文本
*/
public void setMenuItemIconsAndTexts() {
addMenuItems();
}
private int mMenuItemLayoutId = R.layout.homepage_item_layout;
/**
* MenuItem的点击事件接口
*/
private OnMenuItemClickListener mOnMenuItemClickListener;
private float yPosition = 0;
/**
* 添加菜单项
*/
private void addMenuItems() {
LayoutInflater mInflater = LayoutInflater.from(getContext());
/**
* 根据用户设置的参数,初始化view
*/
for (int i = 0; i < mMenuItemCount; i++) {
final int j = i;
View view = mInflater.inflate(mMenuItemLayoutId, this, false);
final ImageView iv = (ImageView) view
.findViewById(R.id.homepage_pager1_item_img);
final TextView tv = (TextView) view
.findViewById(R.id.homepage_pager1_item_tv);
if (iv != null) {
iv.setImageResource(R.mipmap.menu_ture);
}
if (tv != null) {
tv.setText(mItemTexts[i]);
}
view.findViewById(R.id.homepage_item_layout).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
view.findViewById(R.id.homepage_item_layout).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
yPosition = event.getY();//获取按下的位置
iv.setImageResource(R.mipmap.menu);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
iv.setImageResource(R.mipmap.menu_ture);
float displacement = Math.abs(yPosition - event.getY());
//精确按下的位置做出响应
if (mOnMenuItemClickListener != null&&displacement<25) {
mOnMenuItemClickListener.itemClick(v,j);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
iv.setImageResource(R.mipmap.menu_ture);
}
return true;
}
});
addView(view);
}
}
}
源码下载
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# android
# 弧形菜单
# 圆弧菜单
# 弧形Menu
# Android实现自定义的卫星式菜单(弧形菜单)详解
# android图像绘制(七)ClipRect局部绘图/切割原图绘制总结
# android图像绘制(四)自定义一个SurfaceView控件
# android图像绘制(二)画布上放大缩小问题
# android图像绘制(六)获取本地图片或拍照图片等图片资源
# android图像绘制(五)画布保存为指定格式/大小的图片
# android图像绘制(一)多种方法做图像镜像
# android图像绘制(三)画布刷屏问题记录
# Android开发笔记之:在ImageView上绘制圆环的实现方法
# Android编程绘制圆形图片的方法
# Android编程绘图操作之弧形绘制方法示例
# 按下
# 菜单项
# 第一个
# 遍历
# 自定义
# 设置为
# 点到
# 源码下载
# 状态栏
# 发生了
# 屏幕尺寸
# lt
# childMode
# child
# getChildCount
# final
# View
# childSize
# heightMeasureSpec
# text
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
bing浏览器学术搜索入口_bing学术文献检索地址
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
大学网站设计制作软件有哪些,如何将网站制作成自己app?
如何快速辨别茅台真假?关键步骤解析
太平洋网站制作公司,网络用语太平洋是什么意思?
如何为不同团队 ID 动态生成多个非值班状态按钮
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明
Laravel如何使用Collections进行数据处理?(实用方法示例)
公司网站制作需要多少钱,找人做公司网站需要多少钱?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
Laravel如何使用Vite进行前端资源打包?(配置示例)
在Oracle关闭情况下如何修改spfile的参数
如何在万网开始建站?分步指南解析
Laravel Fortify是什么,和Jetstream有什么关系
JavaScript Ajax实现异步通信
百度浏览器如何管理插件 百度浏览器插件管理方法
Laravel如何使用查询构建器?(Query Builder高级用法)
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
浅述节点的创建及常见功能的实现
如何快速搭建虚拟主机网站?新手必看指南
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
如何解决hover在ie6中的兼容性问题
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
如何在自有机房高效搭建专业网站?
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
微信小程序 配置文件详细介绍
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
三星、SK海力士获美批准:可向中国出口芯片制造设备
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
php 三元运算符实例详细介绍
什么是javascript作用域_全局和局部作用域有什么区别?
如何在Windows虚拟主机上快速搭建网站?
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
再谈Python中的字符串与字符编码(推荐)
iOS UIView常见属性方法小结
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
微信小程序 canvas开发实例及注意事项
,在苏州找工作,上哪个网站比较好?
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
大连网站制作公司哪家好一点,大连买房网站哪个好?
Laravel如何使用Service Container和依赖注入?(代码示例)

