android实现筛选菜单效果
作者:我的心里只有你 发布时间:2022-10-22 12:41:05
前言
由于android M的popupwindow与之前版本不一致,笔者找不到能够代码监听物理返回键的方式,故另寻方式实现筛选菜单。5.0及之前的版本可用popupwindow实现,详情请参考popupwindow用法。
本篇采用Dialog实现。
实现步骤
1、设置主题
一般设置如下
<style name="Translucent_NoTitle" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:background">#00000000</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:backgroundDimEnabled">false</item><span style="white-space:pre"> </span>背景暗淡效果
</style>
也可使用android.R.style.Theme_Panel和android.R.style.Theme_Light_Panel。android.R.style.Theme_Panel代码如下,其与上面是一样的。
<style name="Theme.Panel">
<item name="windowBackground">@color/transparent</item>
<item name="colorBackgroundCacheHint">@null</item>
<item name="windowFrame">@null</item>
<item name="windowContentOverlay">@null</item>
<item name="windowAnimationStyle">@null</item>
<item name="windowIsFloating">true</item>
<item name="backgroundDimEnabled">false</item>
<item name="windowIsTranslucent">true</item>
<item name="windowNoTitle">true</item>
</style>
2、设置内容的宽高
我们通过WindowManager.LayoutParams实现。
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.width = screenWidth;
layoutParams.height = contentHeight;
layoutParams.gravity = Gravity.TOP;
layoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; //不阻塞事件传递到后面的窗口
getWindow().setAttributes(layoutParams);
这里,设置layoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 则后面窗口的按钮可响应触摸事件(例,HorizontalScrollView能横向滚动)。
3、设置动画
通过ValueAnimator实现。
enter = ValueAnimator.ofFloat(0, 1f).setDuration(350);
enter.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
dialogContent.setTranslationY((1 - animation.getAnimatedFraction()) * -contentHeight);
}
});
out = ValueAnimator.ofFloat(0, 1f).setDuration(350);
out.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
dialogContent.setTranslationY(animation.getAnimatedFraction() * -contentHeight);
}
});
out.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
dismiss();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
上面enter和out进行一系列设置,对out动画加开始结束监听。enter的start()方法在onStart()中调用
@Override
protected void onStart() {
super.onStart();
dialogContent.post(new Runnable() {
@Override
public void run() {
enter.start();
}
});
}
通过view的post方式,enter.start()会在view hierarchy(view树)构建完后执行(即视图构建完后执行)。view.post源码:
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
第七行为关键代码,ViewRootImpl为视图层级的顶部,实现了view和WindowManager之间的必要协议。RunQueue:运行队列用来排入没有handler关联的view的以后工作。
所以这里dialog的视图显示时会调用enter.start()方法.
监听返回键:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
out.start();
return true;
}
return super.onKeyDown(keyCode, event);
}
out动画执行完后,onAnimationEnd中调用dismiss()方法。
4、在点击的view下显示出来
public void showAsDropView(View view) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.width = screenWidth;
int[] location = new int[2];
view.getLocationOnScreen(location);
// view.getLocationInWindow(location);<span style="white-space:pre"> </span>这里跟上面一句的效果一样,不知有什么区别
lp.y = location[1]-PhoneConstant.statusHeight+view.getHeight();
lp.gravity = Gravity.TOP;
getWindow().setAttributes(lp);
contentTop = location[1];
show();
}
PhoneConstant.statusHeight为状态栏的高度,其通过反射获取
//反射获取状态栏高度
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0, sbar = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
PhoneConstant.statusHeight = getResources().getDimensionPixelSize(x);
} catch(Exception e1) {
e1.printStackTrace();
}
也可通过以下方式获取
Rect outRect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);
不过直接放在activity的onCreate中无效,只有界面绘制出来了才能获取到,可通过view.post()方式获取。
效果图:
另外,继承自AlertDialog的自定义dialog点击edittext不弹出软键盘,所以一般继承自Dialog。
控制对话框输入法的弹出,调用
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
来源:https://blog.csdn.net/y444400/article/details/50706623


猜你喜欢
- 前言很多微信公众号中需要生成推广海报的功能,粉丝获得专属海报后可以分享到朋友圈或发给朋友,为公众号代言邀请好友即可获取奖励的。海报自带渠道二
- 简介简单的文本编译器,可以通过弹出对话框打开文件,进行编写并保存文件。代码package Code.a;import java.io.*;i
- 题目一链表题——操作链表根据给定的链表按照指定条件删除其中节点并返回新的头节点具体题目如下解法/**
- 安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个ACTION_SEND的Intent,系统就为我们弹出
- 首先给大家展示下运行效果图:由于通讯录在手机里是以数据库贮存的 所以我们可以通过一个方法context.getContentResolver
- (1)不需要传递参数,也不需要返回参数ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回
- C#中添加窗口的步骤:1是添加窗口。2是在程序中使用new实例化窗口类对象,并显示窗口。1 添加窗口在解决方案管理器->主项目名称-&
- Android程序调用本机googlemap,传递起始和终点位置,生成路线图if (wodeweizhiPoint != null) { i
- 一个Java程序的执行要经过编译和执行(解释)这两个步骤,同时Java又是面向对象的编程语言。当子类和父类存在同一个方法,子类重写了父类的方
- Android Studio打包.so库到apk中实例详解由于在原来的ADT的Eclipse环境中,用ndk_build工具生成了相应的各个
- OAuth 简介OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordo
- 本文实例讲述了Java实现读取及生成Excel文件的方法。分享给大家供大家参考,具体如下:一、读取Excel文件需要先下载poi-3.0.1
- Android canvas drawBitmap方法详解及实例之前自己在自定义view,用到canvas.drawBitmap
- 本文实例讲述了Android使用Sensor感应器实现线程中刷新UI创建android测力计的功能。分享给大家供大家参考,具体如下:前面一篇
- 方式一:基于现有控件进行扩展,如基于button进行扩展,UI可直接用xmal进行编辑设计,逻辑用xaml.cs进行编辑方法二:直接创建wp
- 1、Redis 怎么保证高可用、有哪些集群模式主从复制、哨兵模式、集群模式。2、主从复制在当前最新的 Redis 6.0 中,主从复制的完整
- 前言在上篇文章(Android实现圆弧滑动效果之ArcSlidingHelper篇)中,我们把圆弧滑动手势处理好了,那么这篇文章我们就来自定
- 啥都不说先上效果图,这个是我项目里的效果:下面的是我抽取出来的 demo 适配啥的我基本上都做好了没做其他的ok 下面 说一下思路把首先 说
- 1.定义Token的注解,需要Token校验的接口,方法上加上此注解import java.lang.annotation.ElementT
- 本文实例为大家分享了C#截取验证码图片的具体代码,供大家参考,具体内容如下使用Graphics类中的DrawImage方法,这个方法有30种