欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现弧形菜单效果

程序员文章站 2022-06-14 09:33:13
前言:公司需求,自己写的一个弧形菜单! 效果: 开发环境:androidstudio2.2.1+gradle-2.14.1 涉及知识:1.自定义控件,2.事件分发...

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

效果:

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);
 }
 }
}

源码下载

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!