转载请注明原创出处,谢谢!
- GitHub: @Ricco
最近开发的项目,用到了Dialog,要求是底部弹出,完全没有问题,这很简单,但是当拿出Android studio的虚拟机[Galaxy Nexus API 25]测试的时候,发现,底部的虚拟按键会阻挡Dialog自己定义的布局,简单的实现一下。
ps:我现在分享的项目代码并没有完美解决,需要配合Activity的布局才能实现。
先上代码
DialogUtil.class 用于隐藏高版本的新手机的虚拟按键
public class DialogUtil {
public static Window getDialogWindow(Context context, Dialog mDialog) {
final Window dialogWindow = mDialog.getWindow();
if (checkDeviceHasNavigationBar(context)) {
//存在的时候设置
dialogWindow.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
dialogWindow.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;
}
dialogWindow.getDecorView().setSystemUiVisibility(uiOptions);
}
});
}
dialogWindow.setGravity(Gravity.BOTTOM);
dialogWindow.setWindowAnimations(R.style.DialogStyle);
return dialogWindow;
}
//判断是否有虚拟按键
private static boolean checkDeviceHasNavigationBar(Context context) {
boolean hasNavigationBar = false;
Resources rs = context.getResources();
int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
hasNavigationBar = rs.getBoolean(id);
}
try {
Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
Method m = systemPropertiesClass.getMethod("get", String.class);
String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
if ("1".equals(navBarOverride)) {
hasNavigationBar = false;
} else if ("0".equals(navBarOverride)) {
hasNavigationBar = true;
}
} catch (Exception e) {
}
return hasNavigationBar;
}
}
MainActivity.class
private Dialog mDialog;
private void showDialog() {
mDialog= new Dialog(this, R.style.MyDialog);
LinearLayout root = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.dialog, null);
// 取消
root.findViewById(R.id.iv_dialog_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDialog.cancel();
}
});
// 确定
root.findViewById(R.id.tv_dialog_ok).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 逻辑
mDialog.cancel();
}
});
// 其他代码...
mDialog.setContentView(root);
Window dialogWindow = DialogUtil.getDialogWindow(this, mDialog);
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 0;
lp.y = -20;
lp.width = getResources().getDisplayMetrics().widthPixels;
root.measure(0, 0);
lp.height = root.getMeasuredHeight();
dialogWindow.setAttributes(lp);
mDialog.show();
}
res/values/styles.xml
<style name="MyDialog">
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<!--控制Dialog出现,消失的动画-->
<style name="DialogStyle" parent="android:Animation">
<item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
<item name="@android:windowExitAnimation">@anim/dialog_exit</item>
</style>
res/anim/dialog_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="100%p" />
</set>
res/anim/dialog_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:toYDelta="100%p" />
</set>