Android实现微博菜单弹出效果
程序员文章站
2022-10-29 16:28:25
先上android仿微博菜单弹出效果图,这个截图不是很流畅,大家可以下载apk试一下。
说一下实现思路:
1、截取当前窗口,对图片做高斯模糊处理,...
先上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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。