Android实现微博菜单弹出效果

先上Android仿微博菜单弹出效果图,这个截图不是很流畅,大家可以下载apk试一下。

说一下实现思路:

1、截取当前窗口,对图片做高斯模糊处理,将处理后的图片做popupwindow的背景图片;
2、创建popupwindow,完成布局,这儿要注意:View的移动范围是由parent的大小决定的,就是只能在parent的范围内移动;
3、给买个View添加进入动画,每个比前一个延期50ms播放动画,关闭窗口时相反;
4、为View的动画添加回弹插值器;

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一下,我后面会持续更新;

下面是apk下载地址:WeiboPopupWindow

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 基于Android实现点击某个按钮让菜单选项从按钮周围指定位置弹出

    Android Material Design:PopupMenu Android Material Design 引入的PopupMenu类似过去的上下文菜单,但是更灵活. 如图所示: 现在给出实现上图PopupMenu的代码. 本例是一个普通的Button触发弹出PopupMenu. 测试的MainActivity.java : package zhangphil.materialdesign; import android.app.Activity; import android.os.B

  • Android仿微信滑动弹出编辑、删除菜单效果、增加下拉刷新功能

    如何为不同的list item呈现不同的菜单,本文实例就为大家介绍了Android仿微信或QQ滑动弹出编辑.删除菜单效果.增加下拉刷新等功能的实现,分享给大家供大家参考,具体内容如下 效果图: 1. 下载开源项目,并将其中的liberary导入到自己的项目中: 2. 使用SwipeMenuListView代替ListView,在页面中布局: <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefresh

  • android自定义popupwindow仿微信右上角弹出菜单效果

    微信右上角的操作菜单看起来很好用,就照着仿了一下,不过是旧版微信的,手里刚好有一些旧版微信的资源图标,给大家分享一下. 不知道微信是用什么实现的,我使用popupwindow来实现,主要分为几块内容: 1.窗口布局文件:popwin_share.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com

  • Android仿QQ滑动弹出菜单标记已读、未读消息

    在上一篇<Android仿微信滑动弹出编辑.删除菜单效果.增加下拉刷新功能>里,已经带着大家学习如何使用SwipeMenuListView这一开源库实现滑动列表弹出菜单,接下来,将进一步学习,如何为不同的list item呈现不同的菜单,此处我们做一个实例:Android 高仿QQ滑动弹出菜单标记已读.未读消息,看下效果图: 1. 创建项目,并导入SwipeMenuListView类库 2. 创建消息实体bean: public class Msg { public int id; publi

  • Android之用PopupWindow实现弹出菜单的方法详解

    在使用UC-WebBrowser时,你会发现它的弹出菜单跟系统自带的菜单不一样.它实现更多菜单选项的显示和分栏.其实,它的本身是PopupWindow或者是AlertDialog对话框,在里面添加两个GridView控件,一个是菜单标题栏,一个是菜单选项.菜单选项视图的切换可以通过适配器的变换,轻松地实现.点击下载该实例:一.运行截图:           二.实现要点:(1)屏蔽系统弹出的菜单:1.首先创建至少一个系统的菜单选项 复制代码 代码如下: @Override public bool

  • android popwindow实现左侧弹出菜单层及PopupWindow主要方法介绍

    PopupWindow可以实现浮层效果,主要方法有:可以自定义view,通过LayoutInflator方法:可以出现和退出时显示动画:可以指定显示位置等. 为了将PopupWindow的多个功能展现并力求用简单的代码实现,编写了一个点击按钮左侧弹出菜单的功能,实现出现和退出时显示动画效果并点击其他区域时弹出层自动消失,效果图如下: 源码: 1.PopwindowOnLeftActivity.java 复制代码 代码如下: package com.pop.main; import android

  • Android仿网易严选底部弹出菜单效果

    在网易严选的看东西的时候在商品详情页里看到他的底部弹出菜单,本能反应是想用DottomSheetDialog或者PopupWindow来实现,可是发现实现不了他那种效果,于是就自己模仿一个像严选这样的底部弹出菜单. 不管是DottomSheetDialog或者PopupWindow他们的阴影背景都是全部覆盖的,这就造成除了菜单内容的View之外其他都是阴影的,而严选不是这样的.唠叨到此,首先展示效果图如下: 是不是还可以呢,由于代码量不多却注释详细,所以先贴出代码再一一详说: BottomPop

  • Android ListView长按弹出菜单二种实现方式示例

    复制代码 代码如下: /** * 知识点1:ListView item:两种长按弹出菜单方式* 知识点2:ListView SimpleAdapter的使用* 知识点 3:在java代码中创建一个ListView*/ public class ListOnLongClickActivity extends Activity {         private LinearLayout myListViewlayout;         private ListView mListView;   

  • Android 关机弹出选择菜单的深入解析

    在Android系统中,长按Power键默认会弹出对话框让你选择"飞行模式","静音","关机"等功能.这些功能对于手机非常适用,但是对于机顶盒产品就没有什么必要了.本文简单介绍一下怎样定制关机界面.我的目标是长按Power键,将会关机,弹出"设备将要关机"选择对话框.如果可以选择"是"关机,和"否"返回系统.弹出对话框的代码位于:frameworks\policies\base\pho

  • android使用PopupWindow实现页面点击顶部弹出下拉菜单

    实现此功能没有太多的技术难点,主要通过PopupWindow方法,同时更进一步加深了PopupWindow的使用,实现点击弹出一个自定义的view,view里面可以自由设计,比较常用的可以放一个listview. demo中我只是一个点击展示,简单的使用了fade in out的动画效果,也没有精美的图片资源,看着也丑,不过这么短的时间,让你掌握一个很好用的技术,可以自己扩展,不很好么? 废话不说了,直接上代码: MainActivity.java public class MainActivi

随机推荐