Android应用开发之Android仿新浪微博首页加号弹出菜单效果
凌雪 2018-10-24 来源 :网络 阅读 1213 评论 0

摘要:本文将带你了解Android应用开发之Android仿新浪微博首页加号弹出菜单效果,希望本文对大家学Android有所帮助。

本文将带你了解Android应用开发之Android仿新浪微博首页加号弹出菜单效果,希望本文对大家学Android有所帮助。


Android仿新浪微博首页加号弹出菜单效果,最近公司项目需求要做一个类似微博的弹出动画,参照网上的资料和自己的修改实现了效果。
先上图:
   
    一、实现思路:
1、截取当前窗口,对图片做高斯模糊处理,将处理后的图片做popupwindow的背景图片;
2、创建popupwindow,完成布局,View的移动范围是由父布局的大小决定的,就是只能在父布局的范围内移动;
3、给每个View添加进入动画,和退出动画,做延时;
4、为View的动画添加回弹插值器;
二、代码实现
弹出窗口代码:package   com.xp.weibopopupwindow; import android.animation.Animator;import   android.animation.Animator.AnimatorListener;import   android.animation.ObjectAnimator;import   android.animation.ValueAnimator;import android.app.Activity;import   android.graphics.Bitmap;import android.graphics.Canvas;import   android.graphics.Paint;import android.graphics.Rect;import   android.graphics.drawable.BitmapDrawable;import android.os.Handler;import   android.util.DisplayMetrics;import android.util.Log;import android.view.Gravity;import   android.view.LayoutInflater;import android.view.View;import   android.view.View.OnClickListener;import android.view.ViewGroup;import   android.widget.ImageView;import android.widget.PopupWindow;import   android.widget.RelativeLayout;import android.widget.Toast; public class   MoreWindow extends PopupWindow implements OnClickListener   {     private String TAG =   MoreWindow.class.getSimpleName();    Activity   mContext;    private int mWidth;    private   int mHeight;    private int   statusBarHeight;    private Bitmap mBitmap =   null;    private Bitmap overlay =   null;     private Handler mHandler = new   Handler();     public MoreWindow(Activity context)   {        mContext =   context;    }     public void   init() {        Rect frame = new   Rect();        mContext.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);        statusBarHeight   = frame.top;        DisplayMetrics   metrics = new   DisplayMetrics();        mContext.getWindowManager().getDefaultDisplay()                .getMetrics(metrics);        mWidth   = metrics.widthPixels;        mHeight   = metrics.heightPixels;         setWidth(mWidth);        setHeight(mHeight);    }     private   Bitmap blur() {        if (null !=   overlay) {            return   overlay;        }        long   startMs = System.currentTimeMillis();         View   view =   mContext.getWindow().getDecorView();        view.setDrawingCacheEnabled(true);        view.buildDrawingCache(true);        mBitmap   =   view.getDrawingCache();         float   scaleFactor = 8;//图片缩放比例        float   radius = 10;//模糊程度        int   width =   mBitmap.getWidth();        int height   =   mBitmap.getHeight();         overlay   = Bitmap.createBitmap((int) (width / scaleFactor), (int) (height /   scaleFactor),   Bitmap.Config.ARGB_8888);        Canvas   canvas = new   Canvas(overlay);        canvas.scale(1   / scaleFactor, 1 / scaleFactor);        Paint   paint = new   Paint();        paint.setFlags(Paint.FILTER_BITMAP_FLAG);        canvas.drawBitmap(mBitmap,   0, 0, paint);         overlay =   FastBlur.doBlur(overlay, (int) radius,   true);        Log.i(TAG, "blur   time is:" + (System.currentTimeMillis() - startMs));        return   overlay;    }     public void   showMoreWindow(View view)   {        final RelativeLayout layout   = (RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.pop_more_window,   null);        setContentView(layout);         ImageView   imgClose = layout.findViewById(R.id.img_close);        imgClose.setOnClickListener(new   OnClickListener()   {             @Override            public   void onClick(View v)   {                if   (isShowing())   {                    closeAnimation(layout);                }            }         });         showAnimation(layout);        setBackgroundDrawable(new   BitmapDrawable(mContext.getResources(),   blur()));        setOutsideTouchable(true);        setFocusable(true);        showAtLocation(view,   Gravity.BOTTOM, 0,   statusBarHeight);    }     private   void showAnimation(ViewGroup layout)   {        for (int i = 0; i <   layout.getChildCount(); i++)   {            final   View child = layout.getChildAt(i);            if   (child.getId() == R.id.img_close)   {                continue;            }            child.setOnClickListener(this);            child.setVisibility(View.INVISIBLE);            mHandler.postDelayed(new   Runnable()   {                 @Override                public   void run()   {                    child.setVisibility(View.VISIBLE);                    ValueAnimator   fadeAnim = ObjectAnimator.ofFloat(child, "translationY", 600,   0);                    fadeAnim.setDuration(300);                    KickBackAnimator   kickAnimator = new KickBackAnimator();                    kickAnimator.setDuration(150);                    fadeAnim.setEvaluator(kickAnimator);                    fadeAnim.start();                }            },   i *   50);        }     }     private   void closeAnimation(ViewGroup layout)   {        for (int i = 0; i <   layout.getChildCount(); i++)   {            final   View child = layout.getChildAt(i);            if   (child.getId() == R.id.img_close)   {                continue;            }            child.setOnClickListener(this);            mHandler.postDelayed(new   Runnable() {                 @Override                public   void run() {                    child.setVisibility(View.VISIBLE);                    ValueAnimator   fadeAnim = ObjectAnimator.ofFloat(child, "translationY", 0,   600);                    fadeAnim.setDuration(200);                    KickBackAnimator   kickAnimator = new   KickBackAnimator();                    kickAnimator.setDuration(100);                    fadeAnim.setEvaluator(kickAnimator);                    fadeAnim.start();                    fadeAnim.addListener(new   AnimatorListener() {                         @Override                        public   void onAnimationStart(Animator animation)   {                            //   TODO Auto-generated method   stub                         }                         @Override                        public   void onAnimationRepeat(Animator animation)   {                            //   TODO Auto-generated method stub                         }                         @Override                        public   void onAnimationEnd(Animator animation) {                            child.setVisibility(View.INVISIBLE);                        }                         @Override                        public   void onAnimationCancel(Animator animation)   {                            //   TODO Auto-generated method   stub                         }                    });                }            },   (layout.getChildCount() - i - 1) *   30);             if   (child.getId() == R.id.tv_text) {                mHandler.postDelayed(new   Runnable()   {                     @Override                    public   void run()   {                        dismiss();                    }                },   (layout.getChildCount() - i) * 30 +   80);            }        }     }     @Override    public   void onClick(View v) {        switch   (v.getId())   {            case   R.id.tv_text:                Toast.makeText(mContext,"点击了文字",Toast.LENGTH_SHORT).show();                break;            case   R.id.tv_lbs:                Toast.makeText(mContext,"点击了签到",Toast.LENGTH_SHORT).show();                break;            case   R.id.tv_photo:                Toast.makeText(mContext,"点击了相册",Toast.LENGTH_SHORT).show();                break;            case   R.id.tv_camera:                Toast.makeText(mContext,"点击了拍摄",Toast.LENGTH_SHORT).show();                break;            case   R.id.tv_more:                Toast.makeText(mContext,"点击了更多",Toast.LENGTH_SHORT).show();                break;            case   R.id.tv_review:                Toast.makeText(mContext,"点击了点评",Toast.LENGTH_SHORT).show();                break;             default:                break;        }    }     public   void destroy() {        if (null !=   overlay)   {            overlay.recycle();            overlay   = null;            System.gc();        }        if   (null != mBitmap)   {            mBitmap.recycle();            mBitmap   =   null;            System.gc();        }    } }
   
   
    高斯模糊码:
 com.xp.weibopopupwindow; import android.graphics.Bitmap; public   class FastBlur {     public static Bitmap   doBlur(Bitmap sentBitmap, int radius,            boolean   canReuseInBitmap) {        Bitmap   bitmap;        if (canReuseInBitmap)   {            bitmap   = sentBitmap;        } else   {            bitmap   = sentBitmap.copy(sentBitmap.getConfig(),   true);        }         if   (radius < 1)   {            return   (null);        }         int   w = bitmap.getWidth();        int h =   bitmap.getHeight();         int[]   pix = new int[w * h];        bitmap.getPixels(pix,   0, w, 0, 0, w, h);         int   wm = w - 1;        int hm = h -   1;        int wh = w * h;        int   p = radius + radius +   1;         int r[] = new   int[wh];        int g[] = new   int[wh];        int b[] = new   int[wh];        int rsum, gsum, bsum,   x, y, i, p, yp, yi, yw;        int   vmin[] = new int[Math.max(w,   h)];         int psum = (p + 1)   >> 1;        psum *=   psum;        int dv[] = new int[256 *   psum];        for (i = 0; i < 256   * psum; i++)   {            dv[i]   = (i /   psum);        }         yw   = yi = 0;         int[][] stack   = new int[p][3];        int   stackpointer;        int   stackstart;        int[]   sir;        int   rbs;        int r1 = radius +   1;        int routsum, goutsum,   boutsum;        int rinsum, ginsum,   binsum;         for (y = 0; y   < h; y++)   {            rinsum   = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =   0;            for   (i = -radius; i <= p="" sir="stack[i">> 16;                sir[1]   = (p & 0x00ff00) >>   8;                sir[2]   = (p & 0x0000ff);                rbs   = r1 -   Math.abs(i);                rsum   += sir[0] * rbs;                gsum   += sir[1] *   rbs;                bsum   += sir[2] * rbs;                if   (i > 0)   {                    rinsum   += sir[0];                    ginsum   +=   sir[1];                    binsum   += sir[2];                }   else   {                    routsum   += sir[0];                    goutsum   +=   sir[1];                    boutsum   += sir[2];                }            }            stackpointer   = radius;             for   (x = 0; x < w; x++)   {                 r[yi]   = dv[rsum];                g[yi]   =   dv[gsum];                b[yi]   = dv[bsum];                 rsum   -=   routsum;                gsum   -=   goutsum;                bsum   -=   boutsum;                 stackstart   = stackpointer - radius +   p;                sir   = stack[stackstart %   p];                 routsum   -=   sir[0];                goutsum   -=   sir[1];                boutsum   -=   sir[2];                 if   (y == 0)   {                    vmin[x]   = Math.min(x + radius + 1,   wm);                }                p   = pix[yw +   vmin[x]];                 sir[0]   = (p & 0xff0000) >>   16;                sir[1]   = (p & 0x00ff00) >>   8;                sir[2]   = (p &   0x0000ff);                 rinsum   +=   sir[0];                ginsum   += sir[1];                binsum   +=   sir[2];                 rsum   += rinsum;                gsum   +=   ginsum;                bsum   += binsum;                 stackpointer   = (stackpointer + 1) %   p;                sir   = stack[(stackpointer) % p];                 routsum   +=   sir[0];                goutsum   += sir[1];                boutsum   +=   sir[2];                 rinsum   -= sir[0];                ginsum   -=   sir[1];                binsum   -=   sir[2];                 yi++;            }            yw   +=   w;        }        for   (x = 0; x < w; x++)   {            rinsum   = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =   0;            yp   = -radius *   w;            for   (i = -radius; i <= yi="Math.max(0," sir="stack[i" rbs="r1" -="" rsum="" gsum="" bsum="" if="" i=""> 0)   {                    rinsum   += sir[0];                    ginsum   +=   sir[1];                    binsum   += sir[2];                }   else   {                    routsum   += sir[0];                    goutsum   +=   sir[1];                    boutsum   += sir[2];                }                 if   (i < hm) {                    yp   +=   w;                }            }            yi   =   x;            stackpointer   =   radius;            for   (y = 0; y < h; y++)   {                //   Preserve alpha channel: ( 0xff000000 & pix[yi]   )                pix[yi]   = (0xff000000 & pix[yi]) | (dv[rsum] <<   16)                        |   (dv[gsum] << 8) | dv[bsum];                 rsum   -=   routsum;                gsum   -= goutsum;                bsum   -=   boutsum;                 stackstart   = stackpointer - radius + p;                sir   = stack[stackstart %   p];                 routsum   -= sir[0];                goutsum   -=   sir[1];                boutsum   -= sir[2];                 if   (x == 0)   {                    vmin[y]   = Math.min(y + r1, hm) * w;                }                p   = x +   vmin[y];                 sir[0]   =   r[p];                sir[1]   =   g[p];                sir[2]   = b[p];                 rinsum   +=   sir[0];                ginsum   += sir[1];                binsum   +=   sir[2];                 rsum   += rinsum;                gsum   +=   ginsum;                bsum   +=   binsum;                 stackpointer   = (stackpointer + 1) %   p;                sir   =   stack[stackpointer];                 routsum   +=   sir[0];                goutsum   +=   sir[1];                boutsum   +=   sir[2];                 rinsum   -=   sir[0];                ginsum   -=   sir[1];                binsum   -=   sir[2];                 yi   += w;            }        }         bitmap.setPixels(pix,   0, w, 0, 0, w, h);         return   (bitmap);    }}
   
   
    回弹效果:
package com.xp.weibopopupwindow; import   android.animation.TypeEvaluator; public class KickBackAnimator   implements TypeEvaluator{    private final   float s = 1.70158f;    float mDuration = 0f;     public   void setDuration(float duration)   {        mDuration =   duration;    }     public Float   evaluate(float fraction, Float startValue, Float endValue)   {        float t = mDuration *   fraction;        float b =   startValue.floatValue();        float   c = endValue.floatValue() -   startValue.floatValue();        float   d = mDuration;        float result =   calculate(t, b, c, d);        return   result;    }     public Float   calculate(float t, float b, float c, float d)   {        return c * ((t = t / d - 1)   * t * ((s + 1) * t + s) + 1) + b;    }}   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved