给大家分享的是Path菜单的简单实现,可以支持自定义方向(左上,右上,右下,左下),并且可以自定义菜单的个数,难点就是菜单的摆放位置 (动态设置margin),还有动画的实现,其实动画只是简单用了个TranslateAnimation
给大家分享的是Path菜单的简单实现,可以支持自定义方向(左上,右上,右下,左下),并且可以自定义菜单的个数,难点就是菜单的摆放位置
(动态设置margin),还有动画的实现,其实动画只是简单用了个TranslateAnimation,N个菜单一起移动的时候感觉很cool~
首先创建一个android工程命名为PathTest.目录结构如下图:
第二步:在values文件夹下新建一个attrs.xml文件,代码如下:
第三步:新建一个PathMenuView.java这个就是我们自定义的Path菜单控件,代码如下:
packagecom.tutor.path;
importandroid.content.Context;
importandroid.content.res.TypedArray;
importandroid.util.AttributeSet;
importandroid.view.Gravity;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.view.animation.Animation;
importandroid.view.animation.AnticipateInterpolator;
importandroid.view.animation.OvershootInterpolator;
importandroid.view.animation.TranslateAnimation;
importandroid.widget.FrameLayout;
importandroid.widget.ImageView;
publicclassPathMenuViewextendsFrameLayout {
privatestaticfinalintLEFT_TOP =0;
privatestaticfinalintRIGHT_TOP =1;
privatestaticfinalintRIGHT_BOTTOM =2;
privatestaticfinalintLEFT_BOTTOM =3;
privateintposition =3;
privateImageView mHome;
privateContext mContext;
privateintmWIDTH =0;
privateintmHEIGHT =0;
privatefloatmDensity;
privatebooleanbMenuShow;
privatestaticintxOffset =15;
privatestaticintyOffset = -13;
privateint[] menuResIds = {R.drawable.composer_camera,R.drawable.composer_music,
R.drawable.composer_sleep,R.drawable.composer_music,R.drawable.composer_place};
publicPathMenuView(Context context){
super(context);
setupViews();
}
publicPathMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.PathMenuView);
position = a.getInt(R.styleable.PathMenuView_position,3);
a.recycle();
setupViews();
}
privatevoidsetupViews(){
mContext = getContext();
mHEIGHT = mContext.getResources().getDisplayMetrics().heightPixels;
mWIDTH = mContext.getResources().getDisplayMetrics().widthPixels;
mDensity = mContext.getResources().getDisplayMetrics().density;
xOffset = (int) (10.667* mDensity);
yOffset = (int) (8.667* mDensity);
mHome = newImageView(mContext);
mHome.setImageResource(R.drawable.composer_button);
mHome.setOnClickListener(listener);
addView(mHome);
LayoutParams mHomeparams = (FrameLayout.LayoutParams)mHome.getLayoutParams();
mHomeparams.width = LayoutParams.WRAP_CONTENT;
mHomeparams.height = LayoutParams.WRAP_CONTENT;
switch(position) {
caseLEFT_TOP:
mHomeparams.gravity = Gravity.LEFT | Gravity.TOP;
for(inti =0; i
intwidth_padding = mWIDTH / ((menuResIds.length -1) *2);
intheight_padding = mHEIGHT / ((menuResIds.length -1) *2);
ImageView imageView = newImageView(mContext);
imageView.setImageResource(menuResIds[i]);
addView(imageView);
LayoutParams params = (FrameLayout.LayoutParams) imageView
.getLayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.leftMargin = mWIDTH / 2
- ((menuResIds.length - i - 1) * width_padding);
params.topMargin = mHEIGHT / 2- i * height_padding;
params.gravity = Gravity.LEFT | Gravity.TOP;
imageView.setLayoutParams(params);
}
break;
caseRIGHT_TOP:
mHomeparams.gravity = Gravity.RIGHT | Gravity.TOP;
for(inti =0; i
intwidth_padding = mWIDTH / ((menuResIds.length -1) *2);
intheight_padding = mHEIGHT / ((menuResIds.length -1) *2);
ImageView imageView = newImageView(mContext);
imageView.setImageResource(menuResIds[i]);
addView(imageView);
LayoutParams params = (FrameLayout.LayoutParams) imageView
.getLayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.rightMargin = mWIDTH / 2
- ((menuResIds.length - i - 1) * width_padding);
params.topMargin = mHEIGHT / 2- i * height_padding;
params.gravity = Gravity.RIGHT | Gravity.TOP;
imageView.setLayoutParams(params);
}
break;
caseRIGHT_BOTTOM:
mHomeparams.gravity = Gravity.RIGHT | Gravity.BOTTOM;
for(inti =0; i
intwidth_padding = mWIDTH / ((menuResIds.length -1) *2);
intheight_padding = mHEIGHT / ((menuResIds.length -1) *2);
ImageView imageView = newImageView(mContext);
imageView.setImageResource(menuResIds[i]);
addView(imageView);
LayoutParams params = (FrameLayout.LayoutParams) imageView
.getLayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.rightMargin = mWIDTH / 2
- ((menuResIds.length - i - 1) * width_padding);
params.bottomMargin = mHEIGHT / 2- i * height_padding;
params.gravity = Gravity.RIGHT | Gravity.BOTTOM;
imageView.setLayoutParams(params);
}
break;
caseLEFT_BOTTOM:
mHomeparams.gravity = Gravity.LEFT | Gravity.BOTTOM;
for(inti =0; i
intwidth_padding = mWIDTH / ((menuResIds.length -1) *2);
intheight_padding = mHEIGHT / ((menuResIds.length -1) *2);
ImageView imageView = newImageView(mContext);
imageView.setImageResource(menuResIds[i]);
addView(imageView);
LayoutParams params = (FrameLayout.LayoutParams)imageView.getLayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.leftMargin = mWIDTH / 2- ((menuResIds.length - i -1) * width_padding);
params.bottomMargin = mHEIGHT / 2- i * height_padding;
params.gravity = Gravity.LEFT | Gravity.BOTTOM;
imageView.setLayoutParams(params);
}
break;
default:
break;
}
mHome.setLayoutParams(mHomeparams);
}
privateOnClickListener listener =newOnClickListener() {
publicvoidonClick(View v) {
if(!bMenuShow) {
startAnimationIn(PathMenuView.this,300);
} else{
startAnimationOut(PathMenuView.this,300);
}
bMenuShow = !bMenuShow;
}
};
privatevoidstartAnimationIn(ViewGroup group,intduration) {
for(inti =1; i
ImageView imageview = (ImageView) group.getChildAt(i);
imageview.setVisibility(0);
MarginLayoutParams mlp = (MarginLayoutParams) imageview
.getLayoutParams();
Animation animation = null;
switch(position) {
caseLEFT_TOP:
animation = newTranslateAnimation(0F,-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset);
break;
caseRIGHT_TOP:
animation = newTranslateAnimation(mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset,0F);
break;
caseLEFT_BOTTOM:
animation = newTranslateAnimation(0F, -mlp.leftMargin+ xOffset, 0F, -yOffset + mlp.bottomMargin);
break;
caseRIGHT_BOTTOM:
animation = newTranslateAnimation(mlp.rightMargin-xOffset,0F,-yOffset + mlp.bottomMargin, 0F);
break;
default:
break;
}
animation.setFillAfter(true);
animation.setDuration(duration);
animation.setStartOffset((i * 100) / (-1+ group.getChildCount()));
animation.setInterpolator(newOvershootInterpolator(2F));
imageview.startAnimation(animation);
}
}
privatevoidstartAnimationOut(ViewGroup group,intduration){
for(inti =1; i
finalImageView imageview = (ImageView) group
.getChildAt(i);
MarginLayoutParams mlp = (MarginLayoutParams) imageview.getLayoutParams();
Animation animation = null;
switch(position) {
caseLEFT_TOP:
animation = newTranslateAnimation(-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset,0F);
break;
caseRIGHT_TOP:
animation = newTranslateAnimation(0F,mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset);
break;
caseLEFT_BOTTOM:
animation = newTranslateAnimation(-mlp.leftMargin+xOffset,0F, -yOffset + mlp.bottomMargin,0F);
break;
caseRIGHT_BOTTOM:
animation = newTranslateAnimation(0F,mlp.rightMargin-xOffset, 0F,-yOffset + mlp.bottomMargin);
break;
default:
break;
}
animation.setFillAfter(true);animation.setDuration(duration);
animation.setStartOffset(((group.getChildCount()-i) * 100)
/ (-1+ group.getChildCount()));
animation.setInterpolator(newAnticipateInterpolator(2F));
imageview.startAnimation(animation);
}
}
}
第四步:PathTestActivity.java以及用到的布局文件main.xml代码如下:
PathTestActivity.java(基本没修改代码)代码如下:
packagecom.tutor.path;
importandroid.app.Activity;
importandroid.os.Bundle;
publicclassPathTestActivityextendsActivity {
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
main.xml代码如下:
xmlns:tutor="http://schemas.android.com/apk/res/com.tutor.path"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tutor:position="right_bottom"
/>
运行点击效果如下:
图1:默认是在右下方这里menuResIds定义了五个菜单 图2:点击红色菜单,菜单收回.
下面我们修改main.xml的tutor属性为left_bottom,并且修改PathMenuView.java中的menuResIds.
tutor:position="left_bottom"
效果如下:
图3:自定义在左下角,六个菜单。