先上效果图,这个截图不是很流畅,大家可以下载apk试一下。
![](https://i-blog.csdnimg.cn/blog_migrate/48e006560b2f525749910694f47b2d56.gif)
说一下实现思路:
1、截取当前窗口,对图片做高斯模糊处理,将处理后的图片做popupwindow的背景图片;
2、创建popupwindow,完成布局,这儿要注意:View的移动范围是由parent的大小决定的,就是只能在parent的范围内移动;
3、给买个View添加进入动画,每个比前一个延期50ms播放动画,关闭窗口时相反;
4、为View的动画添加回弹插值器;
关于动画说明参考:http://gqdy365.iteye.com/blog/2194297
关于截屏并高斯模糊参考:http://gqdy365.iteye.com/blog/2193913
MoreWindow.java窗口
- package com.jerome.weibo;
- 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.view.animation.Animation;
- import android.view.animation.Animation.AnimationListener;
- import android.view.animation.AnimationSet;
- import android.view.animation.TranslateAnimation;
- import android.widget.ImageView;
- import android.widget.PopupWindow;
- import android.widget.RelativeLayout;
- import android.widget.RelativeLayout.LayoutParams;
- 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;
- }
- private Animation showAnimation1(final View view,int fromY ,int toY) {
- AnimationSet set = new AnimationSet(true);
- TranslateAnimation go = new TranslateAnimation(0, 0, fromY, toY);
- go.setDuration(300);
- TranslateAnimation go1 = new TranslateAnimation(0, 0, -10, 2);
- go1.setDuration(100);
- go1.setStartOffset(250);
- set.addAnimation(go1);
- set.addAnimation(go);
- set.setAnimationListener(new AnimationListener() {
- @Override
- public void onAnimationEnd(Animation animation) {
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- @Override
- public void onAnimationStart(Animation animation) {
- }
- });
- return set;
- }
- public void showMoreWindow(View anchor,int bottomMargin) {
- final RelativeLayout layout = (RelativeLayout)LayoutInflater.from(mContext).inflate(R.layout.center_music_more_window, null);
- setContentView(layout);
- ImageView close= (ImageView)layout.findViewById(R.id.center_music_window_close);
- android.widget.RelativeLayout.LayoutParams params =new android.widget.RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
- params.bottomMargin = bottomMargin;
- params.addRule(RelativeLayout.BELOW, R.id.more_window_auto);
- params.addRule(RelativeLayout.RIGHT_OF, R.id.more_window_collect);
- params.topMargin = 200;
- params.leftMargin = 18;
- close.setLayoutParams(params);
- close.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(anchor, 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.center_music_window_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.center_music_window_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.more_window_local){
- 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.more_window_local:
- break;
- case R.id.more_window_online:
- break;
- case R.id.more_window_delete:
- break;
- case R.id.more_window_collect:
- break;
- case R.id.more_window_auto:
- break;
- case R.id.more_window_external:
- break;
- default:
- break;
- }
- }
- public void destroy() {
- if (null != overlay) {
- overlay.recycle();
- overlay = null;
- System.gc();
- }
- if (null != mBitmap) {
- mBitmap.recycle();
- mBitmap = null;
- System.gc();
- }
- }
- }
KickBackAnimator.Java回弹效果:
- package com.jerome.weibo;
- import android.animation.TypeEvaluator;
- public class KickBackAnimator implements TypeEvaluator<Float> {
- 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;
- }
- }
代码见github:
https://github.com/gqdy365/WeiboPopupWindow
请大家star一下,我后面会持续更新;