Android:动画实现精美的弹出框(仿易信)

demo apk下载:链接: http://pan.baidu.com/s/1eQgurse 密码: g91r

截图:

动画效果介绍:

1.点击ActionBar上“+”按钮,菜单从上方弹出(带反弹效果);

2.再次点击“+”、点击空白区域或者点击返回键,菜单向上方收起;

3.点击弹出框上的按钮时,该按钮放大,其它按钮缩小,菜单整体渐变退出。

主体代码:

1.Activity.

/**
 * 仿易信动画弹出框
 */
public class MainActivity extends ActionBarActivity {
    //用于标记页面顶端位置
    private View topView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        topView = findViewById(R.id.main_top);
    }

    private PopupWindow popupWindow;
    private int line1DeltaY, line2DeltaY;

    //仿易信更多弹出框
    private void showPopup() {
        if (popupWindow == null) {
            View contentView = LayoutInflater.from(this).inflate(R.layout.yixin_pop_layout, null);
            //点击空白区域关闭
            View blankView = contentView.findViewById(R.id.yixin_more_blank);
            View blankView2 = contentView.findViewById(R.id.yixin_more_blank2);
            initItems(contentView);

            //测量高度
            int line2Height = ViewUtils.getViewMeasuredHeight(itemViews[0]);
            line1DeltaY = -getActionBarHeight() - 40;
            line2DeltaY = line1DeltaY - line2Height;

            blankView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismissPopup();
                }
            });
            blankView2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismissPopup();
                }
            });

            popupWindow = new PopupWindow(contentView, ScreenUtils.getScreenW(this), ScreenUtils.getScreenH(this));
            //随便设置一个drawable作为背景
            popupWindow.setBackgroundDrawable(new ColorDrawable());
        }

        if (!popupWindow.isShowing()) {
            popupWindow.showAsDropDown(topView, 0, 0);

            for (int i = 0; i < itemViews.length; i++) {
                if (i < 3) {
                    //第一行
                    itemViews[i].startAnimation(AnimationHelper.createPopupAnimIn(this, line1DeltaY));
                } else {
                    //第二行
                    itemViews[i].startAnimation(AnimationHelper.createPopupAnimIn(this, line2DeltaY));
                }
            }
            popupWindow.getContentView().startAnimation(AnimationHelper.createPopupBgFadeInAnim());
        }
    }

    private void dismissPopup() {
        if (popupWindow == null || !popupWindow.isShowing()) {
            return;
        }

        ViewGroup contentView = (ViewGroup) popupWindow.getContentView();
        contentView.startAnimation(AnimationHelper.createPopupBgFadeOutAnim(AnimationHelper.TIME_OUT));

        for (int i = 0; i < itemViews.length; i++) {
            if (i < 3) {
                //第一行
                itemViews[i].startAnimation(AnimationHelper.createPopupAnimOut(this, line1DeltaY));
            } else {
                //第二行
                itemViews[i].startAnimation(AnimationHelper.createPopupAnimOut(this, line2DeltaY));
            }
        }

        //动画结束时隐藏popupWindow
        contentView.postDelayed(new Runnable() {
            @Override
            public void run() {
                popupWindow.dismiss();
            }
        }, AnimationHelper.TIME_OUT + 10);

    }

    private View[] itemViews;

    //初始化popupWindow上的按钮
    private void initItems(View parent) {
        int[] viewIds = new int[]{R.id.yixin_more_item1, R.id.yixin_more_item2, R.id.yixin_more_item3,
                R.id.yixin_more_item4, R.id.yixin_more_item5, R.id.yixin_more_item6};

        itemViews = new View[viewIds.length];
        int itemWidth = ScreenUtils.getScreenW(this) / 3;

        OnClickImpl l = new OnClickImpl();
        for (int i = 0; i < viewIds.length; i++) {
            int id = viewIds[i];
            itemViews[i] = parent.findViewById(id);
            GridLayout.LayoutParams p = (GridLayout.LayoutParams) itemViews[i].getLayoutParams();
            p.width = itemWidth;
            itemViews[i].setLayoutParams(p);

            itemViews[i].setOnClickListener(l);
        }
    }

    private class OnClickImpl implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            final int viewId = v.getId();
            //背景动画
            popupWindow.getContentView().startAnimation(AnimationHelper.createPopupBgFadeOutAnim(AnimationHelper.TIME_OUT_CLICK));
            //动画结束时隐藏popupWindow
            v.postDelayed(new Runnable() {
                @Override
                public void run() {
                    popupWindow.dismiss();

                    //动画结束时响应点击事件
                    handleEvent(viewId);
                }
            }, AnimationHelper.TIME_OUT_CLICK + 10);

            //按钮动画
            for (View item : itemViews) {
                if (item.getId() == v.getId()) {
                    //点击的按钮,放大
                    item.startAnimation(AnimationHelper.createPopupItemBiggerAnim(MainActivity.this));
                } else {
                    //其它按钮,缩小
                    item.startAnimation(AnimationHelper.createPopupItemSmallerAnim(MainActivity.this));
                }
            }
        }
    }

    //popupWindow上按钮的点击事件
    private void handleEvent(int viewId) {
        Toast.makeText(this, "点击了按钮:" + viewId, Toast.LENGTH_SHORT).show();
    }

    private int getActionBarHeight() {
        return getSupportActionBar().getHeight();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_more) {
            if (popupWindow == null || !popupWindow.isShowing()) {
                showPopup();
            } else {
                dismissPopup();
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    //点击返回键时,如果popupWindow是显示状态,则关闭它
    @Override
    public void onBackPressed() {
        if (popupWindow != null && popupWindow.isShowing()) {
            dismissPopup();
            return;
        }

        super.onBackPressed();
    }
}

2.动画工具类。

/**
 * AnimationHelper
 */
public class AnimationHelper {
    /**
     * 进入动画的时间
     */
    public static final int TIME_IN = 300;
    /**
     * 进入动画之后的反弹动画时间
     */
    public static final int TIME_IN_BACK = 100;
    /**
     * 退出动画的时间
     */
    public static final int TIME_OUT = 300;

    /**
     * 点击PopupWindow上菜单后退出动画的时间
     */
    public static final int TIME_OUT_CLICK = 500;

    /**
     * PopupWindow上菜单进入动画
     */
    public static Animation createPopupAnimIn(Context context, int fromYDelta) {
        AnimationSet animationSet = new AnimationSet(context, null);
//        animationSet.setInterpolator(new BounceInterpolator());  //结束时弹跳
        animationSet.setFillAfter(true);

        //移动
        TranslateAnimation translateAnim = new TranslateAnimation(0, 0, fromYDelta, 20);
        translateAnim.setDuration(TIME_IN);
        animationSet.addAnimation(translateAnim);

        //回弹效果
        TranslateAnimation translateAnim2 = new TranslateAnimation(0, 0, 0, -20);
        translateAnim2.setStartOffset(TIME_IN);
        translateAnim2.setDuration(TIME_IN_BACK);
        animationSet.addAnimation(translateAnim2);

        return animationSet;
    }

    /**
     * PopupWindow上菜单离开动画
     */
    public static Animation createPopupAnimOut(Context context, int toYDelta) {
        AnimationSet animationSet = new AnimationSet(context, null);
        animationSet.setFillAfter(true);

        TranslateAnimation translateAnim = new TranslateAnimation(0, 0, 0, toYDelta);
        translateAnim.setDuration(TIME_OUT);
        animationSet.addAnimation(translateAnim);

        return animationSet;
    }

    /**
     * PopupWindow背景进入动画(透明度渐变)
     */
    public static Animation createPopupBgFadeInAnim() {
        AlphaAnimation anim = new AlphaAnimation(0, 1.0f);
        anim.setDuration(TIME_IN);
        anim.setFillAfter(true);
        return anim;
    }

    /**
     * PopupWindow背景离开动画(透明度渐变)
     */
    public static Animation createPopupBgFadeOutAnim(int duration) {
        AlphaAnimation anim = new AlphaAnimation(1.0f, 0);
        anim.setDuration(duration);
        anim.setFillAfter(true);
        return anim;
    }

    /**
     * PopupWindow按钮点击动画
     */
    public static Animation createPopupItemBiggerAnim(Context context) {
        AnimationSet animationSet = new AnimationSet(context, null);
        animationSet.setFillAfter(true);

        //放大(设置缩放的中心点为自己的中心)
        ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnim.setDuration(TIME_OUT_CLICK);
        animationSet.addAnimation(scaleAnim);

        //渐变
        AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0);
        alphaAnim.setInterpolator(new AccelerateInterpolator());
        alphaAnim.setDuration(TIME_OUT_CLICK);
        animationSet.addAnimation(alphaAnim);

        return animationSet;
    }

    /**
     * PopupWindow按钮点击时其它按钮的动画
     */
    public static Animation createPopupItemSmallerAnim(Context context) {
        //放大(设置缩放的中心点为自己的中心)
        ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 0, 1.0f, 0,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnim.setDuration(TIME_OUT_CLICK);
        scaleAnim.setFillAfter(true);

        return scaleAnim;
    }
}

======

完整源码下载:

http://download.csdn.net/detail/books1958/8623665

时间: 2024-10-18 05:41:44

Android:动画实现精美的弹出框(仿易信)的相关文章

【Android】各式各样的弹出框与对菜单键、返回键的监听

Android自带各式各样的弹出框,弹出框也是安卓基本的组件之一.同时安卓程序可以对菜单键.返回键的监听,但在安卓4.0之后就禁止对Home键的屏蔽与监听,强制保留为系统守护按键,如果非要对Home键的屏蔽与监听,就会出现java.lang.IllegalArgumentException: Window type can not be changed after the window is added.的错误. 下面写一个小程序,来说明Android各式各样的弹出框,同时,安卓是如何对菜单键.

Bootstarp学习(二十三)模态弹出框(Modals)

这一小节我们先来讲解一个"模态弹出框",插件的源文件:modal.js. 右侧代码编辑器(30行)就是单独引入 bootstrap 中发布出的"modal.js"文件. 样式代码: ? LESS版本:modals.less ? Sass版本:_modals.scss ? 编译后的Bootstrap:对应bootstrap.css文件第5375行-第5496行 在 Bootstrap 框架中把模态弹出框统一称为 Modal.这种弹出框效果在大多数 Web 网站的交互中

jQuery+css3弹出框插件

先来看DEMO:https://codepen.io/jonechen/pen/regjGG 插件的开发很简单,运用了CSS3的动画效果,并且弹出框的内容可以自定义.插件的默认配置参数有三个: var defaults = { event: 'click', // 默认点击事件 dialogBox: 'selector', // 弹出框容器 hover: false, // 默认滑动事件关闭 } CSS部分: *{padding: 0; margin: 0; list-style: none;f

Android 学习笔记之AndBase框架学习(二) 使用封装好的进度框,Toast框,弹出框,确认框...

PS:渐渐明白,在实验室呆三年都不如在企业呆一年... 学习内容: 1.使用AbActivity内部封装的方法实现进度框,Toast框,弹出框,确认框...   AndBase中AbActivity封装好了许多方法提供我们去使用,使得在使用的时候更加的方便,只需要传递相关参数即可..省去了我们自己使用基础的函数进行构造...   就好比进度框,Toast框,弹出框,确认框...这些基本的东西都在AndBase的AbActivity封装好了...我们只需要传递参数调用其中内部的方法就可以完成这些视

自定义PopupWindow弹出框(带有动画)

使用PopupWindow来实现弹出框,并且带有动画效果 首先自定义PopupWindow 1 public class LostPopupWindow extends PopupWindow { 2 public Lost lost; 3 public void onLost(Lost lost){ 4 this.lost = lost; 5 } 6 private View conentView; 7 8 public View getConentView() { 9 return cone

android 弹出框(输入框和选择框)

1.输入框: final EditText inputServer = new EditText(this); inputServer.setFilters(new InputFilter[]{new InputFilter.LengthFilter(50)}); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("个性点的签名").setIcon(android.R.drawab

android popwindow仿微信右上角弹出框,dialog底部显示

仿微信右上角弹出框 1.利用popwindow实现 2.popwindow的位置居于右上角 新建,弹出popwindow: /** 弹popwindow **/ <span style="white-space:pre"> </span>tv = (TextView) findViewById(R.id.textView1); <span style="white-space:pre"> </span>view_pop

android如何使用DOM来解析XML+如果做一个表情的弹出框

效果图: 如何解析以下的xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <array> <string>(#大笑)</string

Android窗口为弹出框样式

1.XML android:theme="@android:style/Theme.Dialog <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fish.helloworld" android:versio