Android的Dialog弹出时隐藏导航栏效果,目前认为的最优解
原本Android的ProgressDialog用法很简单,两三行代码就搞定了。但是,但是,但是,用在无人值守的自助终端上,总是把之前隐藏掉的导航栏和状态栏显示出来。这是不可接受的。总不能让设备给用户随意摆弄吧,进入系统把你应用给搞没了都有可能。
项目中用到一个Android的ProgressDialog显示操作的进度条,机器要求是屏蔽或隐藏掉导航栏和虚拟按键的显示。
但是试了好多方法,也参考了网上的很多做法,隐藏安卓底部导航栏之后 弹出dialog或者popupwindow后,导航栏会再次显示出来,虽然可以设置在dialog的onStart中再次隐藏导航栏,但是会出现一个导航栏显示出来又马上隐藏掉的一个效果。这样会很影响体验,会闪一下虚拟栏再隐藏,或者隐藏了再显示回来。
经过一连串的尝试摸索,找到了个目前认为是见到过的最优解的方法。
如果谁有更好更简单的实现,欢迎留言,共同学习学习。
其间遇到过问题:
android.util.AndroidRuntimeException: requestFeature() must be called before adding content
这个错是因为调用的顺序问题,网上有解决办法。
在Activity中隐藏状态栏,要在setContentView(R.layout.activity_main)之前调用。
而Dialog中,需要在dialog.show()方法之后去调用。
将alert.setCentView(xx);
alertDialog.getWindow();
放到alertDialog.show();
后边调用。
至于原因,网上有人从源码的角度分析过这个问题。多学习多研究还是很有好处的,能够进一步提高能力。
在Activity中,虽然在setContentView(R.layout.activity_main)之前调用隐藏状态栏的代码,但是一旦Activity跳转,就又出来了,
解决办法是在隐藏状态栏逻辑代码的下面,加上一个状态栏变化的响应处理,在把它隐藏掉。
如下:
/**
* 隐藏虚拟按键:必须放到setContentView前面
*/
protected void hideBottomUIMenu() {
//隐藏虚拟按键,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getWindow().getDecorView();
// int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
// int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_FULLSCREEN;
// int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// | View.INVISIBLE |
// View.SYSTEM_UI_FLAG_FULLSCREEN
// |View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.INVISIBLE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View .SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
protected void showBottomUIMenu() {
//隐藏虚拟按键,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.VISIBLE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView =this.getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
//调用如下:
//在BaseActivity的OnCreate中,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hideBottomUIMenu();
this.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
hideBottomUIMenu();
}
});
//setOrientation();
//setContentView(initLayout());
if (getLayResId() > 0) {
setContentView(getLayResId());
}
}
如何解决上述问题呢,直接封装一个类,继承自ProcessDialog,并且实现了调整默认字体的方法,
往下不多说了。直接贴出来代码:
package com.newcapec.smartorder.dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
/**
* Created by yangyongzhen on 2019/05/22.
*/
public class MyProgressDialog extends ProgressDialog {
private Window window;
public MyProgressDialog(Context context) {
super(context);
this.window = getWindow();
}
/**
* dialog 需要全屏的时候用,和clearFocusNotAle() 成对出现
* 在show 前调用 focusNotAle show后调用clearFocusNotAle
*
* @param window
*/
private void focusNotAle(Window window) {
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}
/**
* dialog 需要全屏的时候用,focusNotAle() 成对出现
* 在show 前调用 focusNotAle show后调用clearFocusNotAle
*
* @param window
*/
private void clearFocusNotAle(Window window) {
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}
/**
* 隐藏虚拟栏 ,显示的时候再隐藏掉
*
* @param window
*/
public void hideNavigationBar(final Window window) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
window.getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
//布局位于状态栏下方
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
//全屏
View.SYSTEM_UI_FLAG_FULLSCREEN |
//隐藏导航栏
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if (Build.VERSION.SDK_INT >= 19) {
uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
} else {
uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
window.getDecorView().setSystemUiVisibility(uiOptions);
}
});
}
@Override
public void show() {
focusNotAle(window);
super.show();
hideNavigationBar(window);
clearFocusNotAle(window);
}
public void setTextSize(View v, int size) {
if (v instanceof ViewGroup) {
ViewGroup parent = (ViewGroup) v;
int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
View child = parent.getChildAt(i);
setTextSize(child, size);
}
} else if (v instanceof TextView) {
((TextView) v).setTextSize(size);
}
}
}
关于如何使用这个类,贴出来封装的一个工具类,支持调整进度条的透明度和长宽高,显示位置等属性:
package com.newcapec.smartorder.utils;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Point;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import com.newcapec.smartorder.dialog.MyProgressDialog;
/**
* Created by yangyongzhen on 2019/05/22.
*/
public class ProgressDialogUtils {
private static MyProgressDialog mProgressDialog;
/**
* 显示ProgressDialog
*
* @param context
* @param message
*/
public static void showProgressDialog(Context context, CharSequence message) {
if (mProgressDialog == null) {
mProgressDialog = new MyProgressDialog(context);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);// 设置进度条的形式为圆形转动的进度条
mProgressDialog.setCancelable(true);// 设置是否可以通过点击Back键取消
mProgressDialog.setCanceledOnTouchOutside(true);// 设置在点击Dialog外是否取消Dialog进度条
mProgressDialog.setMessage(message);
mProgressDialog.show();
Point size = new Point();
mProgressDialog.getWindow().getWindowManager().getDefaultDisplay().getSize(size);
int width = size.x;//获取界面的宽度像素
int height = size.y;
WindowManager.LayoutParams params = mProgressDialog.getWindow().getAttributes();//一定要用mProgressDialog得到当前界面的参数对象,否则就不是设置ProgressDialog的界面了
params.alpha = 0.8f;//设置进度条背景透明度
params.height = height / 8;//设置进度条的高度
params.gravity = Gravity.LEFT;//设置ProgressDialog的重心
params.x = 90;
params.width = 3 * width / 5;//设置进度条的宽度
params.dimAmount = 0f;//设置半透明背景的灰度,范围0~1,系统默认值是0.5,1表示背景完全是黑色的,0表示背景不变暗,和原来的灰度一样
mProgressDialog.getWindow().setAttributes(params);//把参数设置给进度条,注意,一定要先show出来才可以再设置,不然就没效果了,因为只有当界面显示出来后才可以获得它的屏幕尺寸及参数等一些信息
View v = mProgressDialog.getWindow().getDecorView();
mProgressDialog.setTextSize(v,24);
mProgressDialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);
// }
// });
} else {
mProgressDialog.show();
}
//setDialogText(v);
//隐藏状态栏和底部的虚拟键
}
/**
* 关闭ProgressDialog
*/
public static void dismissProgressDialog() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
- 如何找出被黑客攻击后篡改的WordPress 文件?
- 移动设备HTML5页面布局
- Foundation:高级的响应式前端框架
- [信息安全] 2.密码工具箱(续)
- 脑科学发展的助推器
- BFIThumb:WordPress 中替代TimThumb 进行裁图的选择
- jquery 操作ajax 相关方法
- SQL SERVER 2008 Hierarchyid数据类型
- Html5 学习利器 Web Standards Update for Microsoft Visual Studio 2010 SP1
- MongoDB 客户端 MongoVue
- HttpClient介绍
- 10个使用 Foundation 框架开发的WordPress 主题推荐
- jQuery 效果使用
- 几款更换WordPress 后台UI 的插件推荐
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- c语言二级指针的使用,malloc内存申请
- istio部署模型
- 你所不知道的printf函数
- c语言之——整型的隐式转换与溢出检测
- Istio 的配置分析
- (C99)复合字面量
- 排障集锦:九九八十一难之第十三难!-------------史上最全MySQL 单实例故障排查
- c语言数组越界的避免方法
- 单片机的存储区范例
- 大点干!早点散----------Nginx+Tomcat动静分离
- 大点干!早点散----------深入剖析缓存加速--squid传统代理和透明代理
- stm32 HardFault_Handler调试及问题查找方法——飞思卡尔
- 堆栈的分布
- memset()函数的使用
- 质量保障的方法和实践