概述
现在很多App会在入口比较浅的页面添加一些快捷操作入口,一方面是为了方便用户操作,一方面是为了提高产品一些关键入口的使用率,让用户能够在浏览信息流的过程中能快速切换至其他一些功能页面。例如豆瓣的首页 (右下角红框选中部分):
豆瓣菜单
本文将仿照这种菜单效果进行实现,最终效果如下:
弧形菜单效果图
需要定制的特性
1.菜单展开半径
2.设置菜单主按钮Icon
3.设置菜单子项的各个Icon
4.展开和收缩的动画时长
5.所有菜单按钮的宽高
6.是否在展开收缩的同时旋转主按钮
注:理论上可以设置无数个菜单项,但是会出现重叠情况(空间有限),这种情况得自行调整按钮数量和宽高。
实现思路
可以看到这个菜单是由多个按钮组合而成,所以可以考虑用ViewGroup来作为载体,其中的子View再通过属性动画进行配合达成效果,而各个菜单项的弹出角度可以针对90°来进行弧度平分,再通过三角函数得到最终展开的目标坐标,关键要注意View的宽高边距的计算,否则可能会出现超出边界的情况。
1)初始化基本框架
由于菜单是由多个按钮叠加在一个平面,所以可以考虑采用继承FrameLayout,然后根据设置的Icon资源Id的数量来作为按钮的数量进行初始化,代码如下:List mImgViews = new ArrayList<>();
List mMenuItemResIds = new ArrayList<>(); /**
* 初始化主按钮
* @param context
*/
private void initMenuView(Context context) {
mMenuIv = new ImageView(context);
mMenuIv.setImageResource(mMenuResId);
FrameLayout.LayoutParams params = new LayoutParams(mMenuWidth, mMenuWidth);
params.bottomMargin = mMenuItemWidth / 2;
params.rightMargin = mMenuItemWidth / 2;
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
addView(mMenuIv, params);
mMenuIv.setOnClickListener(this);
} /**
* 初始化菜单子项按钮
* @param context
*/
private void initMenuItemViews(Context context) {
mImgViews.clear(); for (int index = 0; index
ImageView menuItem = new ImageView(context);
menuItem.setImageResource(mMenuItemResIds.get(index));
FrameLayout.LayoutParams params = new LayoutParams(mMenuItemWidth, mMenuItemWidth);
params.bottomMargin = mMenuItemWidth / 2;
params.rightMargin = mM