Skip to content

Repository files navigation

YMenuView

欢迎 Star or Fork!有什么意见和建议可以在Issue上提出。

(前面是之前YMenuView1.x的效果,后面是新加的)

传送门

YMenuView1.x分析

YMenuView2.x分析

自定义YMenu教程

简介

这是一个类似Path菜单的自定义View,这是经过大改版之后的YMenuView2.x,之前1.x版本的README。2.x版本可以自定义MenuButton和OptionButton的布局和显示消失动画,效果可参考上图,下面来开始看看如何自定义炫酷的YMenu吧。

使用

Gradle

 compile 'com.yanzhikaijky:YMenuView:2.0.1'

抽象类YMenu

2.x版本后由之前单一的YMenuView把一些通用逻辑提取出来形成了抽象父类YMenu,开放出4个抽象方法来让用户自定义MenuButton和OptionButton的布局和显示消失动画,而YMenuView的功能则没有变化,增加了3个YMenu的子类,实现了不同的效果。

属性

和1.x版本相比,属性名字有所改变

属性名称意义类型默认值
menuButtonWidth菜单键宽度dimension80px
menuButtonHeight菜单键高度dimension80px
optionButtonWidth选项键宽度dimension80px
optionButtonHeight选项键高度dimension80px
menuButtonRightMargin menuToParentXMargin菜单键距离YMenuView边缘距离dimension50px
menuButtonBottomMargin menuToParentYMargin菜单键距离YMenuView边缘距离dimension50px
optionToMenuRightMargin optionToParentXMargin选项键距离YMenuView边缘距离dimension35px
optionToMenuBottomMargin optionToParentYMargin选项键距离YMenuView边缘距离dimension160px
optionHorizontalMargin optionXMargin选项键之间水平间距dimension15px
optionVerticalMargin optionYMargin选项键之间垂直间距dimension15px
menuButtonBackGround菜单键背景Drawablereference@drawable/setting
optionsBackGround选项键背景Drawablereference@drawable/null_drawable
optionPositionCounts“选项”占格个数integer8
optionColumns“选项”占格列数integer1
isShowMenu一开始时是否展开菜单booleanfalse
sd_duration进出动画耗时integer600
sd_animMode进出动画选择enumFROM_BUTTON_TOP

由于YMenuView2.0重构之后实现了继承YMenu可以实现各种布局,所以下图只是参考YMenu的一个子类——YMenuView的属性,MenuButton和OptionButton都是依靠右下边缘。

对应的sd_animMode模式有(这是YMenuView特有的):

sd_animMode描述
FROM_BUTTON_LEFT选项从菜单键左边缘飞入
FROM_BUTTON_TOP选项从菜单键上边缘飞入
FROM_RIGHT选项从View左边缘飞入
FROM_BOTTOM选项从View左边缘飞入

除了上面的XML属性的set、get方法,还有下面的一些重要方法:

 //清除所有View,用于之后刷新
private void cleanMenu(){
removeAllViews();
if (optionButtonList != null) {
optionButtonList.clear();
}
isShowMenu = false;
if (onPreDrawListener != null) {
getViewTreeObserver().removeOnPreDrawListener(onPreDrawListener);
}
}
/*
* 对整个YMenuView进行重新初始化,用于在做完一些设定之后刷新
*/
public void refresh(){
cleanMenu();
init(mContext);
}
//获取实际的OptionButton数量
public int getOptionButtonCount() //设置MenuButton弹出菜单选项时候MenuButton自身的动画,默认为顺时针旋转180度,为空则是关闭动画
public void setMenuOpenAnimation(Animation menuOpenAnimation) //设置MenuButton收回菜单选项时候MenuButton自身的动画,默认为逆时针旋转180度,为空则是关闭动画
public void setMenuCloseAnimation(Animation menuCloseAnimation) /*
* 下面的set方法需要在View还没有初始化的时候调用,例如Activity的onCreate方法里
* 如果不在View还没初始化的时候调用,请使用完set这些方法之后调用refresh()方法刷新
*/
//设置OptionButton的Drawable资源
public void setOptionDrawableIds(int... drawableIds) //设置禁止放置选项的位置序号,注意不能输入负数、重复数字或者大于等于optionPositionCounts的数,会报错。
public void setBanArray(int... banArray) 

**PS: **banArray里面设置的位置序号就是告诉YMenuView不要在那个位置上放置OptionButton,所以这里有一条规则就是:optionPositionCounts >= banArray.length + drawableIds.length

点击监听

实现YMenuView.OnOptionsClickListener接口,重写里面的onOptionsClick()方法即可:

public class MainActivity extends AppCompatActivity implements YMenuView.OnOptionsClickListener{
private YMenuView mYMenuView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mYMenuView = (YMenuView) findViewById(R.id.ymv);
mYMenuView.setOnOptionsClickListener(this);
}
@Override
public void onOptionsClick(int index) {
switch (index){
case 0:
makeToast("0");
break;
case 1:
makeToast("1");
break;
case 2:
makeToast("2");
break;
case 3:
makeToast("3");
break;
case 4:
makeToast("4");
break;
case 5:
makeToast("5");
break;
}
}
private void makeToast(String str){
Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
}

YMenu其他子类

Circle8YMenu

这是一个OptionButton围绕着MenuButton的布局,Option最大数量为8个,MenuButton的位置位于ViewGroup正中间,如果想改变的话可以继承Circle8YMenu,单单重写setMenuPosition()方法就可以了,这个是以optionXMargin为圆的半径。

TreeYMenu

这是一个OptionButton分布成分叉树的布局,Option最大数量为9个,MenuButton的位置位于ViewGroup中下方,支持了menuToParentYMargin属性。

SquareYMenu

这是一个OptionButton和MenuButton组成正方形的布局,Option最大数量为8个,MenuButton为位置依靠右下,支持了menuToParentYMarginmenuToParentXMargin属性。

自定义YMenu

这里才是YMenuView2.x的重头戏,但是由于篇幅过长,可以跳转到自定义YMenu教程查看。

demo演示

ViewGroup的宽高

由于YMenuView是用ViewGroup来实现的,所以如果选项OptionButton的位置超出YMenuView的范围的话,会出现不能收回的情况。demo里面使用的是match_parent,实际中使用可以把YMenuView放到其他视图的上层。

YMenu的子类实现演示

Demo里面的activity_main.xml有效果图上各种效果的YMenu实现定义,查看的时候只要反注释一下,就可以运行了,xml里面的格式如下:

 <!--右下角纵向8个-->
<!--<com.yanzhikai.ymenuview.YMenuView-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:id="@+id/ymv"-->
<!--app:optionPositionCounts="8"-->
<!--app:optionColumns="1"-->
<!--app:menuButtonBackGround="@drawable/setting"-->
<!--app:optionsBackGround="@drawable/background_option_button" />-->
<!--右下角3竖8个-->
...
<!--右下角横向5个-->
...
<!--Circle8-->
...
<!--Tree-->
...
<!--Square-->
...

Ban列表式

YMenuView1.x就有有Ban功能,能把一些位置设为不放置OptionButton,那么YMenuView2.0也支持这个,例如:

 //对Circle8YMenu
mYMenu.setBanArray(0,2,4,6);

 //对TreeYMenu
mYMenu.setBanArray(2,8,7);

 //对SquareYMenu
mYMenu.setBanArray(3,4,7,5,6);

但是动画延时还是会算上不被填充的位置,这暂时无法避免,所以想要更好的体验效果的话就继承YMenu重写方法吧。

更新

  • version 2.0.0:2017/09/21 全新版本更新:可以实现自定义YMenu,增加3个YMenu类型,原YMenuView现在也是YMenu的一个子类。
  • version 2.0.1:2017/09/25 修复isShowMenu属性设置无效问题,增加menu_duration属性,用于设置MenuButton的动画时长。

后续

可能会实现自定义动画,还有给这些OptionButton加上轨迹等。

开源协议

YMenuView遵循Apache 2.0开源协议。

关于作者

id:炎之铠

炎之铠的邮箱:yanzhikai_yjk@qq.com

CSDN:http://blog.csdn.net/totond

YMenuView原理分析博客: YMenuView1.x分析:http://blog.csdn.net/totond/article/details/77364137 YMenuView2.x分析:http://blog.csdn.net/totond/article/details/78059196

About

a menuView similar to PathMenu

Resources

Stars

52 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages