弧形菜单(Android)

前言:公司需求,自己写的一个弧形菜单!

效果:

开发环境: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)的更多相关文章

  1. Android 自定义View修炼-Android 实现自定义的卫星式菜单(弧形菜单)View

    一.总述 Android 实现卫星式菜单也叫弧形菜单的主要要做的工作如下:1.动画的处理2.自定义ViewGroup来实现卫星式菜单View (1)自定义属性       a. 在attrs.xml中 ...

  2. 原生js写的一个弧形菜单插件

    弧形菜单是一种半弧式或者全弧形菜单,是一种不同于传统横向或者竖向菜单形式的菜单.最近在网上看到好多人写出了这种效果,于是也尝试自己写了一个. 实现方式:原生态js 主要结构: 1.参数合并 var d ...

  3. 弧形菜单2(动画渐入)Kotlin开发(附带java源码)

    弧形菜单2(动画渐入+Kotlin开发) 前言:基于AndroidStudio的采用Kotlin语言开发的动画渐入的弧形菜单...... 效果: 开发环境:AndroidStudio2.2.1+gra ...

  4. 菜单(Menu)的三中创建方式——Android开发之路2

    菜单的三种创建方式 一.OptionsMenu---选项菜单 Android应用中的菜单默认是隐藏的,只有当用户点击手机上的MENU键,系统才会显示菜单.这种菜单叫做选项菜单(Options Menu ...

  5. Android侧滑菜单代码实现

    前两天学习了hyman老师讲的Android侧滑菜单的实现,经过自己的整理分享出来给大家学习一下 现在很多APP都有菜单侧滑的功能,本篇文章主要讲解使用自定义的HorizontalScrollView ...

  6. android上下文菜单

    XML: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmln ...

  7. Android课程---进度条及菜单的学习

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Android学习笔记之树形菜单的应用...

    PS:终于考完试了,总算是解脱了...可以正式上手项目开发了.... 学习内容: 1.掌握如何使用树形菜单...   对知识点进行一下补充...居然忘记了去学习树形菜单...不过在这里补上... Ex ...

  9. Android 菜单(OptionMenu)

    菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu). 一.概述 ...

随机推荐

  1. [转] Vagrant入门

    [From] https://www.cnblogs.com/davenkin/p/vagrant-virtualbox.html 简单地说,Vagrant让我们可以通过代码的方式快速地.可重复地创建 ...

  2. 经典C面试真题精讲

    第一章 灵魂--指针 101. p++ 请分析下述代码的输出结果 int main() { char* p1 = "China"; char* p2, * p3; p2 = (); ...

  3. Linux安装python3.6.3

    一: (1)wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz 下载安装包 (可以到网站下载,然后上传到Linux) (2)ta ...

  4. RMQ(求区间最值问题)

    学习博客:https://blog.csdn.net/qq_31759205/article/details/75008659 RMQ(Range Minimum/Maximum Query),即区间 ...

  5. 怎么用代码弹回 UITableView 中左滑出来的删除按钮

    点击取消,让删除按钮弹回去 [tableView setEditing:NO] 初学 ios 真是大菜鸟,这么简单的一个问题搞了 3 个小时

  6. 403 for URL: http://www.terracotta.org/kit/reflector

    前面因为在一个项目中使用了ehcache.xml配置文件,后面启动tomcat的时候报下面的错误 java.io.IOException: Server returned HTTP response ...

  7. Git使用总结(一):简介与基本操作

    一:简介 GIT是一个开源的分布式的版本控制系统,是由Linus 为了管理Linux内核开发而开发的一个开源的版本控制软件.相比SVN,它采用分布式版本库方式. 二:工作区,暂存区和版本库 左侧为工作 ...

  8. Wamp设置虚拟目录

    1. 默认安装 wamp后,工作目录为"..../wamp/www" 也就是PHP文件只有放在此目录下才能打得开,打开Apache的配置文件httpd.conf可以看到: 这么两行 ...

  9. .NET加密技术概述

    微软.NET 的System.Security.Cryptography中的类实现了各种具体的加密算法和技术.这些类,有一些是非托管 Microsoft CryptoAPI 的包装,而另一些则是纯粹的 ...

  10. badboy详解篇

    上一篇学习了jmeter录制的两种方法,badboy是比较好用的一个,它本身就是个测试工具,今天具体来介绍一下: 1.检查点 检查点就是记录被测系统某个值的预期结果 以百度搜索gogomall为例子 ...