本来是写一个底部弹出的dialog,背后一个半透明的背景。
很简单的一个需求。
1、写个布局
2、写个class继承Dialog。
public class ChooseWeChatDialog extends AppCompatDialog {
<style name="DefaultDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否开启半透明的背景 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 半透明的背景的透明度 -->
<item name="android:backgroundDimAmount">0.6</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowActionBar">true</item>
</style>
3、重写构造函数,传入theme
public ChooseWeChatDialog(FragmentActivity context, OnClickBack onClickBack) {
super(context, R.style.DefaultDialog);
this.mContext = context;
this.onClickBack = onClickBack;
}
4、重写onCreate方法设置布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View contentView = LayoutInflater.from(mContext).inflate(R.layout.dialog_wechat_choose, null);
ll_wechat = contentView.findViewById(R.id.ll_wechat);
ll_wechat_friend = contentView.findViewById(R.id.ll_wechat_friend);
setCanceledOnTouchOutside(true);
setContentView(contentView);
然后show起来,然后发现出问题了,出来的结果是这样的
顶部的状态栏和底部的当行栏都带了系统自带的那个背景,顶部不用管,就是我想要的效果(现在是蓝色是因为底部的Activity还没有设置成沉浸式的)。但是底部就不行,看上就和格格不入。
就想着给底部改个颜色,白色就可以,想着TM挺简单的一个东西,改了两天没改好。
一个是自己太菜,不知道设置这东西的原理,只有到处去找别人实现的代码复制下来看效果,不满意又再换。结果你抄我我抄你的,试了两天都没有一个代码是生效的。
废话了, 最后这这么搞的:
1、dialog这样显示是因为没有全屏,底部导航栏的显示还在系统上,所以改不了。那么就先让dialog全屏,怎么让dialog全屏呢,通过theme就可以,把现在dialog的Theme的parent改成这个(为啥是这个,我也不知道为啥,但是这个效果是能满足我的)
<style name="DefaultDialog" parent="@android:style/Theme.Holo.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.6</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowActionBar">true</item>
</style>
2、这个时候你就发现是全屏了,但是底部导航栏直接变成黑色了,那就说明导航栏还是没给你,这个时候在代码中给dialog设置沉浸式的状态栏和导航栏(代码放在dialog 的 onCreat里面就可以,不用在show之后)
// 保证dialog宽度占满
Window window = getWindow();
window.setGravity(Gravity.BOTTOM);
window.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(layoutParams);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
WindowManager.LayoutParams lp = getWindow().getAttributes();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
getWindow().setAttributes(lp);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
} else {//4.4 全透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
3、这个时候你就会发现dialog的展示放到了导航栏的下面,这是个好现象。你就可以在dialog的下面写一个白色背景的View,然后把这个view的高度设置为导航栏的高度
LinearLayout.LayoutParams vParams = (LinearLayout.LayoutParams) v_line.getLayoutParams();
vParams.height = ScreenUtils.getNavigationHeight(mContext);
v_line.setLayoutParams(vParams);
好了,这样看上去就正常了,虽然不是很优雅。但像我这种CV工程师,也就这个水平了。如果你有更好的办法,还请告诉我。
上个最后的效果图吧