Android实现弹出菜单背景模糊效果
龙旋
共 7634字,需浏览 16分钟
· 2022-05-09
效果图:
使用的PopupWindow实现的,主要部分有:
背景揭露动画+ 旋转动画,菜单项弹出动画。
先看pop的布局文件:
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rel"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@id/blurring_view"
android:layout_width="match_parent"
app:radius="17"
app:overlayColor="#66eeeeee"
android:layout_height="match_parent"
/>
android:id="@+id/lin"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentBottom="true"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:orientation="horizontal">
android:id="@+id/tv_sbs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:gravity="center_horizontal"
android:layout_marginTop="50dp"
android:drawablePadding="10dp"
android:drawableTop="@mipmap/ic_more_sbs"
android:text="发布身边事"
android:textColor="@color/col_text2"
android:textSize="15sp" />
android:id="@+id/tv_search"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:clickable="true"
android:drawablePadding="10dp"
android:drawableTop="@mipmap/ic_more_search"
android:gravity="center_horizontal"
android:text="搜索"
android:textColor="@color/col_text2"
android:textSize="15sp" />
android:id="@+id/tv_course"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginTop="50dp"
android:layout_height="wrap_content"
android:clickable="true"
android:drawablePadding="10dp"
android:drawableTop="@mipmap/ic_more_open_course"
android:gravity="center_horizontal"
android:text="我要开课"
android:textColor="@color/col_text2"
android:textSize="15sp" />
android:id="@+id/tv_task"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_weight="1"
android:clickable="true"
android:drawablePadding="10dp"
android:drawableTop="@mipmap/ic_more_task"
android:gravity="center_horizontal"
android:text="发布任务"
android:textColor="@color/col_text2"
android:textSize="15sp" />
android:id="@+id/rel_close"
android:layout_width="wrap_content"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
android:id="@+id/iv_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="15dp"
android:src="@mipmap/ic_more_close" />
java代码实现:
public class MoreWindow extends PopupWindow implements OnClickListener {
private Activity mContext;
private RelativeLayout layout;
private ImageView close;
private View bgView;
private BlurringView blurringView;
private int mWidth;
private int mHeight;
private int statusBarHeight;
private Handler mHandler = new Handler();
public MoreWindow(Activity context) {
mContext = context;
}
/**
* 初始化
* @param view 要显示的模糊背景View,一般选择跟布局layout
*/
public void init(View view) {
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);
layout = (RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.center_music_more_window, null);
setContentView(layout);
close = (ImageView) layout.findViewById(R.id.iv_close);
close.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isShowing()) {
closeAnimation();
}
}
});
blurringView = (BlurringView) layout.findViewById(R.id.blurring_view);
blurringView.blurredView(view);//模糊背景
bgView = layout.findViewById(R.id.rel);
setOutsideTouchable(true);
setFocusable(true);
setClippingEnabled(false);//使popupwindow全屏显示
}
public int getNavigationBarHeight(Activity activity) {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
//获取NavigationBar的高度
int height = resources.getDimensionPixelSize(resourceId);
return height;
}
/**
* 显示window动画
* @param anchor
*/
public void showMoreWindow(View anchor) {
showAtLocation(anchor, Gravity.TOP | Gravity.START, 0, 0);
mHandler.post(new Runnable() {
@Override
public void run() {
try {
//圆形扩展的动画
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
int x = mWidth / 2;
int y = (int) (mHeight - DensityUtils.fromDpToPx(25));
Animator animator = ViewAnimationUtils.createCircularReveal(bgView, x,
y, 0, bgView.getHeight());
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
// bgView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
// layout.setVisibility(View.VISIBLE);
}
});
animator.setDuration(300);
animator.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
showAnimation(layout);
}
private void showAnimation(ViewGroup layout) {
try {
LinearLayout linearLayout = layout.findViewById(R.id.lin);
mHandler.post(new Runnable() {
@Override
public void run() {
//+ 旋转动画
close.animate().rotation(90).setDuration(400);
}
});
//菜单项弹出动画
for (int i = 0; i < linearLayout.getChildCount(); i++) {
final View child = linearLayout.getChildAt(i);
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(200);
KickBackAnimator kickAnimator = new KickBackAnimator();
kickAnimator.setDuration(150);
fadeAnim.setEvaluator(kickAnimator);
fadeAnim.start();
}
}, i * 50 + 100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关闭window动画
*/
private void closeAnimation() {
mHandler.post(new Runnable() {
@Override
public void run() {
close.animate().rotation(-90).setDuration(400);
}
});
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
int x = mWidth / 2;
int y = (int) (mHeight - DensityUtils.fromDpToPx(25));
Animator animator = ViewAnimationUtils.createCircularReveal(bgView, x,
y, bgView.getHeight(), 0);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
// layout.setVisibility(View.GONE);
}
@Override
public void onAnimationEnd(Animator animation) {
// bgView.setVisibility(View.GONE);
dismiss();
}
});
animator.setDuration(300);
animator.start();
}
} catch (Exception e) {
}
}
/**
* 点击事件处理
* @param v
*/
@Override
public void onClick(View v) {
if (isShowing()) {
closeAnimation();
}
switch (v.getId()) {
case R.id.tv_sbs:
break;
case R.id.tv_search:
break;
case R.id.tv_course:
break;
case R.id.tv_task:
break;
}
}
}
还有一个菜单项回弹的插值器:
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;
}
}
使用:
初始化
mMoreWindow = new MoreWindow(this);
mMoreWindow.init(idContainer);
点击+按钮时弹出
private void showMoreWindow() {
if (null == mMoreWindow) {
mMoreWindow = new MoreWindow(this);
mMoreWindow.init(idContainer);
}
mMoreWindow.showMoreWindow(idContainer );
}
其中的idContainer为当前Activity的跟布局layout。
源码地址:
https://github.com/DuShuYuan/PlusMenu
到这里就结束啦。
评论
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
SpringBoot+Minio实现上传凭证、分片上传、秒传和断点续传
关注我们,设为星标,每天7:40不见不散,架构路上与您共享回复架构师获取资源大家好,我是你们的朋友架构君,一个会写代码吟诗的架构师。Spring Boot整合Minio后,前端的文件上传有两种方式:1、文件上传到后端,由后端保存到Minio这种方式好处是完全由后端集中管理,可以很好的做到、身份验证、
Java架构师社区
0
第二十四届中国·盱眙国际龙虾节重点活动菜单发布!
今天盱眙龙虾开捕活动现场发布第二十四届中国·盱眙国际龙虾节重点活动菜单盱眙老妹微信自媒体主要从事:品牌推广︎、活动策划︎、微信平台营销代运营︎、免费发布公益便民信息、企业招聘︎、商标注册、征婚交友、公益救助、维权爆料等服务。欢迎广大网友积极参与。免责声明:盱眙老妹微信平台是面向普通网友的信息发布平台
盱眙老妹
0
超越原生,散点图实现华夫饼图
之前我们介绍过了如何使用新卡片图实现华夫饼图。参考:超越原生,PowerBI 华夫饼图实现但是利用卡片图实现的华夫饼图有一些缺点,形状之间的大小跟间距不太好把握,而且有时形状大一点的话显示就会不正常,需要做出二次调整。今天给大家介绍一种原生视觉对象生成华夫饼图的更佳方案,既简单又美观。上图是利用散点
PowerBI战友联盟
2
全新 SOTA backbone | 2024年了,再见ViT系列Backbone,实数难得,不知道效果如何?
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达在构建用于精确匹配的深度固定长度表示时,确定指纹上的密集特征点,特别是在像素 Level 上,具有重大意义。为了探索指纹匹配的可解释性,作者提出了一种多阶段可解释的指纹匹配网络,名为通过视觉 Transformer 进行指纹匹配的
小白学视觉
10
Spring Boot + flowable 快速实现工作流
关注我们,设为星标,每天7:40不见不散,架构路上与您共享回复架构师获取资源大家好,我是你们的朋友架构君,一个会写代码吟诗的架构师。来源:blog.csdn.net/zhan107876/article/details/120815560总览一、flowable-ui部署运行二、绘制流程图绘图细节:
Java架构师社区
0
实现订单30分钟自动取消的策略
原文:juejin.cn/post/7285167401821798400简介在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例
JAVA乐园
0
AI大模型之路 第三篇:从零实现词嵌入模型,加深理解!
你好,我是郭震今天我们研究「AI大模型第三篇」:词维度预测,很多读者听过词嵌入,这篇文章解答下面问题:词嵌入是什么意思?怎么做到的?原理是什么?从零实现一个专属你数据集的词嵌入我们完整从零走一遍,根基的东西要理解透,这样才能发明出更好的东西。1 skip-gram模型Skip-gram模型是一种广泛
Python与算法社区
11