Android实现弹力伸缩式菜单

2026-04-01 22:50:59

1、自定义相对布局I114gBoxRelativeLayout类,源码如下:

/**

 * 

 */

package com.i114gbox.sdk.ui;

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import android.view.animation.Animation;

import android.widget.RelativeLayout;

import com.i114gbox.sdk.animation.I114gBoxZoomAnimation;

import com.i114gbox.sdk.utils.I114gBoxLogUtils;

/**

 * 自定义相对布局

 * 

 * @author shenjichao@vivagame.cn

 * 

 */

public class I114gBoxRelativeLayout extends RelativeLayout {

private static String TAG = "I114gBoxRelativeLayout";

private Animation mAnimation;// 动画对象

public I114gBoxRelativeLayout(Context ctx) {

super(ctx);

}

public I114gBoxRelativeLayout(Context ctx, AttributeSet attrs) {

super(ctx, attrs);

}

public I114gBoxRelativeLayout(Context ctx, AttributeSet attrs, int defStyle) {

super(ctx, attrs, defStyle);

}

/** 开始指定的动画 **/

@Override

public void startAnimation(Animation animation) {

I114gBoxLogUtils.d(TAG, "The startAnimation method execute.");

super.startAnimation(animation);

this.mAnimation = animation;

this.getRootView().postInvalidate();// 刷新界面,不需要Handler,是工作者线程

// this.getRootView().invalidate();//刷新界面,需要被主线程调用,需要Handler

}

/** 通知和目前有关的视图动画开始 **/

@Override

protected void onAnimationStart() {

I114gBoxLogUtils.d(TAG, "The onAnimationStart method execute.");

super.onAnimationStart();

if (this.mAnimation instanceof I114gBoxZoomAnimation) {

setVisibility(View.VISIBLE);

}

}

/** 通知和目前有关的视图动画结束 **/

@Override

protected void onAnimationEnd() {

I114gBoxLogUtils.d(TAG, "The onAnimationEnd method execute.");

super.onAnimationEnd();

if (this.mAnimation instanceof I114gBoxZoomAnimation) {

setVisibility(((I114gBoxZoomAnimation) mAnimation).mDirection != I114gBoxZoomAnimation.Direction.HIDE ? View.GONE

: View.VISIBLE);

}

}

}

2、自定义图片按钮控件I114gBoxImageButton类,源码如下:

/**

 * 

 */

package com.i114gbox.sdk.ui;

import com.i114gbox.sdk.animation.I114gBoxZoomAnimation;

import com.i114gbox.sdk.utils.I114gBoxLogUtils;

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import android.view.animation.Animation;

import android.widget.ImageButton;

/**

 * 自定义ImageButton

 * 

 * @author shenjichao@vivagame.cn

 * 

 */

public class I114gBoxImageButton extends ImageButton {

private static String TAG = "I114gBoxImageButton";

private Animation mAnimation;// 动画对象

public I114gBoxImageButton(Context ctx) {

super(ctx);

}

public I114gBoxImageButton(Context ctx, AttributeSet attrs) {

super(ctx, attrs);

}

public I114gBoxImageButton(Context ctx, AttributeSet attrs, int defStyle) {

super(ctx, attrs, defStyle);

}

@Override

public void startAnimation(Animation animation) {

I114gBoxLogUtils.d(TAG, "The startAnimation method execute.");

super.startAnimation(animation);

this.mAnimation = animation;

this.getRootView().postInvalidate();

}

@Override

protected void onAnimationStart() {

I114gBoxLogUtils.d(TAG, "The onAnimationStart method execute.");

super.onAnimationStart();

if (this.mAnimation instanceof I114gBoxZoomAnimation) {

setVisibility(View.VISIBLE);

}

}

@Override

protected void onAnimationEnd() {

I114gBoxLogUtils.d(TAG, "The onAnimationEnd method execute.");

super.onAnimationEnd();

if (this.mAnimation instanceof I114gBoxZoomAnimation) {

setVisibility(((I114gBoxZoomAnimation) mAnimation).mDirection != I114gBoxZoomAnimation.Direction.HIDE ? View.GONE

: View.VISIBLE);

}

}

}

3、include到主layout中的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:clipChildren="false"

        android:clipToPadding="false" >

        <com.i114gbox.sdk.ui.I114gBoxRelativeLayout

            android:id="@id/rl_menus_wrapper"

            android:layout_width="match_parent"

            android:layout_height="120dip"

            android:layout_alignParentBottom="true"

            android:layout_alignParentLeft="true"

            android:clipChildren="false"

            android:clipToPadding="false"

            android:focusable="true" >

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_photo"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="10dp"

                android:background="@drawable/menu_tapjoy"

                android:visibility="gone" />

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_people"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="55dp"

                android:background="@drawable/menu_qq"

                android:visibility="gone" />

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_place"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="100dp"

                android:background="@drawable/menu_wechat"

                android:visibility="gone" />

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_music"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="145dp"

                android:background="@drawable/menu_sina_weibo"

                android:visibility="gone" />

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_thought"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="190dp"

                android:background="@drawable/menu_facebook"

                android:visibility="gone" />

            <com.i114gbox.sdk.ui.I114gBoxImageButton

                android:id="@+id/menu_sleep"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_alignParentBottom="true"

                android:layout_alignParentLeft="true"

                android:layout_marginBottom="100.0px"

                android:layout_marginLeft="235dp"

                android:background="@drawable/menu_alipay"

                android:visibility="gone" />

        </com.i114gbox.sdk.ui.I114gBoxRelativeLayout>

        <com.i114gbox.sdk.ui.I114gBoxRelativeLayout

            android:id="@id/rl_menu_main_shrink"

            android:layout_width="60dp"

            android:layout_height="50dp"

            android:layout_alignParentBottom="true"

            android:layout_centerHorizontal="true"

            android:background="@drawable/main_center_button" >

            <ImageView

                android:id="@id/iv_menu_main_plus"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_centerInParent="true"

                android:contentDescription="@string/menu"

                android:src="@drawable/menu_icn_plus" />

        </com.i114gbox.sdk.ui.I114gBoxRelativeLayout>

    </RelativeLayout>

</LinearLayout>

4、实现菜单项打开时的动画效果:

// 获取菜单添加视图

imageViewPlus = findViewById(I114gBoxResourceUtils.getId(ctx,

"iv_menu_main_plus"));

// 获取菜单包裹视图组,存放多个菜单项

menusWrapper = (ViewGroup) findViewById(I114gBoxResourceUtils.getId(

ctx, "rl_menus_wrapper"));

// 获取菜单添加视图的布局

menuShrinkView = findViewById(I114gBoxResourceUtils.getId(ctx,

"rl_menu_main_shrink"));

// layoutMain = (RelativeLayout) findViewById(R.id.layout_content);

// 打开菜单时,顺时针动画

animRotateClockwise = AnimationUtils.loadAnimation(ctx,

I114gBoxResourceUtils.getAnimId(ctx, "menu_rotate_clockwise"));

// 关闭菜单时,逆时针动画

animRotateAntiClockwise = AnimationUtils.loadAnimation(ctx,

I114gBoxResourceUtils.getAnimId(ctx,

"menu_rotate_anticlockwise"));

// 添加监听事件

menuShrinkView.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

showLinearMenus();// 显示菜单项

}

});

for (int i = 0; i < menusWrapper.getChildCount(); i++) {

menusWrapper.getChildAt(i).setOnClickListener(

new SpringMenuLauncher(intentActivity[i]));

}

/**

* 显示菜单项

*/

private void showLinearMenus() {

int[] size = I114gBoxSystemManagerUtils.getScreenSize(ctx);// 获取屏幕高度和宽度

if (!areMenusShowing) {// 当菜单未打开时

I114gBoxAnimation.startAnimations(this.menusWrapper,

Direction.SHOW, size);

this.imageViewPlus.startAnimation(this.animRotateClockwise);

} else {// 当菜单已打开时

I114gBoxAnimation.startAnimations(this.menusWrapper,

Direction.HIDE, size);

this.imageViewPlus.startAnimation(this.animRotateAntiClockwise);

}

areMenusShowing = !areMenusShowing;

}

private class I114gBoxMenuLauncher implements OnClickListener {

private final Class<?> cls;

private int resource;

private I114gBoxMenuLauncher(Class<?> c, int resource) {

this.cls = c;

this.resource = resource;

}

private I114gBoxMenuLauncher(Class<?> c) {

this.cls = c;

}

public void onClick(View v) {

MainActivity.this.startOpenMenuAnimations(v);// 打开菜单项动画

Intent intent = new Intent(ctx, cls);

ctx.startActivity(intent);

}

}

/** 打开菜单项动画 **/

private void startOpenMenuAnimations(View view) {

areMenusShowing = true;

Animation inAnimation = new I114gBoxShrinkAnimationOut(300);

Animation outAnimation = new I114gBoxEnlargeAnimationOut(300);

inAnimation.setInterpolator(new AnticipateInterpolator(2.0F));

// inAnimation.setInterpolator(new CycleInterpolator(2.0F));

inAnimation.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationEnd(Animation animation) {

MainActivity.this.imageViewPlus.clearAnimation();

}

@Override

public void onAnimationRepeat(Animation animation) {

}

@Override

public void onAnimationStart(Animation animation) {

}

});

view.startAnimation(outAnimation);

}

5、顺时针动画定义:

<?xml version="1.0" encoding="UTF-8"?>

<rotate

    xmlns:android="http://schemas.android.com/apk/res/android" 

android:interpolator="@android:anim/linear_interpolator"

android:duration="200"

android:fromDegrees="0.0"

android:toDegrees="225.0"

android:pivotX="50.0%"

android:pivotY="50.0%"

android:fillAfter="true"

android:fillEnabled="true"/>

逆时针动画定义:

<?xml version="1.0" encoding="UTF-8"?>

<rotate

    xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/linear_interpolator"

android:duration="200"

android:fromDegrees="225.0"

android:toDegrees="0.0"

android:pivotX="50.0%"

android:pivotY="50.0%"

android:fillAfter="true"

android:fillEnabled="true"/>

猜你喜欢