Android实现弹力伸缩式菜单 - Go语言中文社区

Android实现弹力伸缩式菜单


利用Android中自带的动画效果来实现弹力伸缩式菜单,默认情况下,菜单项为隐藏状态,当点击某一图标,打开菜单项,则通过一系列动画效果实现菜单项的展示;当再次点击该图标时,关闭菜单项,则通过一系列动画实现菜单项的隐藏。效果图如下:


实现原理:

利用Android设置动画的同时,并使用插入器(interpolator)来实现弹力

OvershootInterpolator插入器,表示向前甩出一定值后再回到之前的位置

AnticipateOvershootInterpolator插入器,表示开始的时候向后,然后向前甩

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"/>

6、逆时针动画定义:

<?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"/>

注意:

<1>需要定义顺时针和逆时针动画文件
<2>需要将动画效果和插入器相结合

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/shenjichao2008/article/details/21610475
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 10:56:27
  • 阅读 ( 1138 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢