Hi~大家好,出来创业快3个月了,一切还不错,前一段时间用了业余时间搞了个问答类网站YQMA.想做中国的stackoverflow,哈哈,只是YY下,希望大家多多支持!
好了,今天给大家分享的是Path菜单的简单实现,可以支持自定义方向(左上,右上,右下,左下),并且可以自定义菜单的个数,难点就是菜单的摆放位置(动态设置margin),还有动画的实现,其实动画只是简单用了个TranslateAnimation,N个菜单一起移动的时候感觉很cool~
这里也用到了自定义标签,这里不懂的童鞋可以看我 Android高手进阶教程(四)之----Android 中自定义属性(attr.xml,TypedArray)的使用! 这篇文章.好了废话不多说了,
首先创建一个android工程命名为PathTest.目录结构如下图:

第二步:在values文件夹下新建一个attrs.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="PathMenuView"><attr name="position"><enum name="left_top" value="0"></enum> <enum name="right_top" value="1"></enum> <enum name="right_bottom" value="2"></enum> <enum name="left_bottom" value="3"></enum> </attr> </declare-styleable></resources>
第三步:新建一个PathMenuView.Java这个就是我们自定义的Path菜单控件,代码如下:
package com.tutor.path;import androidcontentContext; import androidcontentresTypedArray; import androidutilAttributeSet; import androidviewGravity; import androidviewView; import androidviewViewGroup; import androidviewanimationAnimation; import androidviewanimationAnticipateInterpolator; import androidviewanimationOvershootInterpolator; import androidviewanimationTranslateAnimation; import androidwidgetFrameLayout; import androidwidgetImageView; /*** @author frankiewei* 超级仿path菜单* position定义菜单的位置,目前支持:左上;右上;右下;左下四个方向。* menuResIds定义出现的菜单的资源ID*/ public class PathMenuView extends FrameLayout {private static final int LEFT_TOP = 0;private static final int RIGHT_TOP = 1;private static final int RIGHT_BOTTOM = 2;private static final int LEFT_BOTTOM = 3; /*** 默认的位置是在右下角*/ private int position = 3;/*** 那个圆形菜单*/ private ImageView mHome;/*** 上下文*/ private Context mContext; /*** 设备的宽度*/ private int mWIDTH = 0;/*** 设备的高度*/ private int mHEIGHT = 0;/*** 设备的density*/ private float mDensity;/*** 菜单是否显示*/ private boolean bMenuShow;private static int xOffset = 15; private static int yOffset = -13;/*** 菜单的资源个数*/ private int[] menuResIds = {Rdrawablecomposer_camera,Rdrawablecomposer_music, Rdrawablecomposer_sleep,Rdrawablecomposer_music,Rdrawablecomposer_place}; public PathMenuView(Context context){ super(context); setupViews(); }public PathMenuView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = contextobtainStyledAttributes(attrs,RstyleablePathMenuView);position = agetInt(RstyleablePathMenuView_position,3);arecycle(); setupViews(); }private void setupViews(){ mContext = getContext();mHEIGHT = mContextgetResources()getDisplayMetrics()heightPixels; mWIDTH = mContextgetResources()getDisplayMetrics()widthPixels; mDensity = mContextgetResources()getDisplayMetrics()density;xOffset = (int) (667 * mDensity); yOffset = (int) (667 * mDensity);mHome = new ImageView(mContext);mHomesetImageResource(Rdrawablecomposer_button); mHomesetOnClickListener(listener);addView(mHome);LayoutParams mHomeparams = (FrameLayoutLayoutParams)mHomegetLayoutParams(); mHomeparamswidth = LayoutParamsWRAP_CONTENT; mHomeparamsheight = LayoutParamsWRAP_CONTENT;switch (position) { case LEFT_TOP: mHomeparamsgravity = GravityLEFT | GravityTOP; for (int i = 0; i < menuResIdslength; i++) {int width_padding = mWIDTH / ((menuResIdslength - 1) * 2); int height_padding = mHEIGHT / ((menuResIdslength - 1) * 2);ImageView imageView = new ImageView(mContext); imageViewsetImageResource(menuResIds[i]); addView(imageView); LayoutParams params = (FrameLayoutLayoutParams) imageView getLayoutParams(); paramswidth = LayoutParamsWRAP_CONTENT; paramsheight = LayoutParamsWRAP_CONTENT; paramsleftMargin = mWIDTH / 2 - ((menuResIdslength - i - 1) * width_padding); paramstopMargin = mHEIGHT / 2 - i * height_padding; paramsgravity = GravityLEFT | GravityTOP; imageViewsetLayoutParams(params);}break; case RIGHT_TOP: mHomeparamsgravity = GravityRIGHT | GravityTOP; for (int i = 0; i < menuResIdslength; i++) {int width_padding = mWIDTH / ((menuResIdslength - 1) * 2); int height_padding = mHEIGHT / ((menuResIdslength - 1) * 2);ImageView imageView = new ImageView(mContext); imageViewsetImageResource(menuResIds[i]); addView(imageView); LayoutParams params = (FrameLayoutLayoutParams) imageView getLayoutParams(); paramswidth = LayoutParamsWRAP_CONTENT; paramsheight = LayoutParamsWRAP_CONTENT; paramsrightMargin = mWIDTH / 2 - ((menuResIdslength - i - 1) * width_padding); paramstopMargin = mHEIGHT / 2 - i * height_padding; paramsgravity = GravityRIGHT | GravityTOP; imageViewsetLayoutParams(params);} break; case RIGHT_BOTTOM: mHomeparamsgravity = GravityRIGHT | GravityBOTTOM; for (int i = 0; i < menuResIdslength; i++) {int width_padding = mWIDTH / ((menuResIdslength - 1) * 2); int height_padding = mHEIGHT / ((menuResIdslength - 1) * 2);ImageView imageView = new ImageView(mContext); imageViewsetImageResource(menuResIds[i]); addView(imageView); LayoutParams params = (FrameLayoutLayoutParams) imageView getLayoutParams(); paramswidth = LayoutParamsWRAP_CONTENT; paramsheight = LayoutParamsWRAP_CONTENT; paramsrightMargin = mWIDTH / 2 - ((menuResIdslength - i - 1) * width_padding); paramsbottomMargin = mHEIGHT / 2 - i * height_padding; paramsgravity = GravityRIGHT | GravityBOTTOM; imageViewsetLayoutParams(params);} break; case LEFT_BOTTOM: mHomeparamsgravity = GravityLEFT | GravityBOTTOM; for(int i = 0; i < menuResIdslength; i++){int width_padding = mWIDTH / ((menuResIdslength - 1) * 2); int height_padding = mHEIGHT / ((menuResIdslength -1) * 2);ImageView imageView = new ImageView(mContext); imageViewsetImageResource(menuResIds[i]); addView(imageView); LayoutParams params = (FrameLayoutLayoutParams)imageViewgetLayoutParams(); paramswidth = LayoutParamsWRAP_CONTENT; paramsheight = LayoutParamsWRAP_CONTENT;paramsleftMargin = mWIDTH / 2 - ((menuResIdslength - i - 1) * width_padding); paramsbottomMargin = mHEIGHT / 2 - i * height_padding; paramsgravity = GravityLEFT | GravityBOTTOM; imageViewsetLayoutParams(params);} break; default: break; }mHomesetLayoutParams(mHomeparams);}private OnClickListener listener = new OnClickListener() {public void onClick(View v) { if (!bMenuShow) { startAnimationIn(PathMenuViewthis, 300); } else { startAnimationOut(PathMenuViewthis, 300); } bMenuShow = !bMenuShow; } }; /*** 菜单隐藏动画** @param group* @param duration*/ private void startAnimationIn(ViewGroup group, int duration) { for (int i = 1; i < groupgetChildCount(); i++) { ImageView imageview = (ImageView) groupgetChildAt(i); imageviewsetVisibility(0); MarginLayoutParams mlp = (MarginLayoutParams) imageview getLayoutParams(); Animation animation = null; switch (position) { case LEFT_TOP: animation = new TranslateAnimation(0F,-mlpleftMargin+xOffset,0F,-mlptopMargin + yOffset); break; case RIGHT_TOP: animation = new TranslateAnimation(mlprightMargin - xOffset,0F,-mlptopMargin + yOffset,0F); break;case LEFT_BOTTOM: animation = new TranslateAnimation(0F, -mlpleftMargin+ xOffset, 0F, -yOffset + mlpbottomMargin); break;case RIGHT_BOTTOM: animation = new TranslateAnimation(mlprightMargin-xOffset,0F,-yOffset + mlpbottomMargin, 0F); break; default: break; }animationsetFillAfter(true); animationsetDuration(duration); animationsetStartOffset((i * 100) / (-1 + groupgetChildCount())); animationsetInterpolator(new OvershootInterpolator(2F)); imageviewstartAnimation(animation);} }/*** 菜单显示动画** @param group* @param duration*/ private void startAnimationOut(ViewGroup group,int duration){ for (int i = 1; i < groupgetChildCount(); i++) { final ImageView imageview = (ImageView) group getChildAt(i); MarginLayoutParams mlp = (MarginLayoutParams) imageviewgetLayoutParams();Animation animation = null;switch (position) { case LEFT_TOP: animation = new TranslateAnimation(-mlpleftMargin+xOffset,0F,-mlptopMargin + yOffset,0F); break; case RIGHT_TOP: animation = new TranslateAnimation(0F,mlprightMargin - xOffset,0F,-mlptopMargin + yOffset); break;case LEFT_BOTTOM: animation = new TranslateAnimation(-mlpleftMargin+xOffset,0F, -yOffset + mlpbottomMargin,0F); break;case RIGHT_BOTTOM: animation = new TranslateAnimation(0F,mlprightMargin-xOffset, 0F,-yOffset + mlpbottomMargin); break; default: break; }animationsetFillAfter(true);animationsetDuration(duration); animationsetStartOffset(((groupgetChildCount()-i) * 100) / (-1 + groupgetChildCount())); animationsetInterpolator(new AnticipateInterpolator(2F)); imageviewstartAnimation(animation); } }}
第四步:PathTestActivity.java以及用到的布局文件main.xml代码如下:
PathTestActivity.java(基本没修改代码)代码如下:
package comtutorpath;import androidappActivity; import androidosBundle;public class PathTestActivity extends Activity {@Override public void onCreate(Bundle savedInstanceState) { superonCreate(savedInstanceState); setContentView(Rlayoutmain); } }
main.xml代码如下:
<?xml version="0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemasandroidcom/apk/res/android" xmlns:tutor="http://schemasandroidcom/apk/res/comtutorpath" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" ><comtutorpathPathMenuView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="fill_parent" tutor:position="right_bottom"/></LinearLayout>
运行点击效果如下:

图1:默认是在右下方这里menuResIds定义了五个菜单

图2:点击红色菜单,菜单收回.
下面我们修改main.xml的tutor属性为left_bottom,并且修改PathMenuView.java中的menuResIds.
tutor:position="left_bottom"
效果如下:

图3:自定义在左下角,六个菜单。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。