带有半透明状态栏的全屏 DialogFragment

Posted

技术标签:

【中文标题】带有半透明状态栏的全屏 DialogFragment【英文标题】:Fullscreen DialogFragment with translucent StatusBar 【发布时间】:2015-04-01 19:18:29 【问题描述】:

我有一个想要全屏显示的 DialogFragment。然而,我仍然想要一个状态栏,以及底部的硬件按钮。我还想设置 StatusBar 的背景颜色(用于 Lollipop)。

我的问题是,如果我在 DialogFragment 中设置以下标志:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);   
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

StatusBar 和 Hardware 键盘都变成半透明的,DialogFragment 在它们后面延伸。

这是代码,已大大简化为可读性:

public class CardDetailsDialog extends DialogFragment 

Setup parameters...

public static CardDetailsDialog newInstance(final long cardId, final long projectId)
    CardDetailsDialog frag = new CardDetailsDialog();
    frag.setStyle(DialogFragment.STYLE_NORMAL, R.style.CardDetailsDialogStyle);
    return frag;


@Override
public void onActivityCreated(Bundle savedInstanceState) 
    super.onActivityCreated(savedInstanceState);
    if(getDialog() != null) 
        getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogSlideAnimation;
        getDialog().getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        getDialog().getWindow().setStatusBarColor(Color.RED);
    


@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    super.onCreateView(inflater, container, savedInstanceState);
    View view = inflater.inflate(R.layout.card_details, container, false);

    Handle everything that happens inside the view...

    return view;


这里是引用的主题:

<style name="CardDetailsDialogStyle" parent="@style/Theme.AppCompat.Light.Dialog" >
    <item name="android:windowBackground">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>

以及片段的样式:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@color/pp.whiteBackgroundColor" >

<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_details_toolbar"
    android:layout_
    android:layout_
    android:layout_alignParentTop="true"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/PopupMenutheme">
</android.support.v7.widget.Toolbar>

    <ScrollView
        android:id="@+id/details_scrollview"
        android:layout_
        android:layout_>

        All subview elements here...

    </ScrollView>

</RelativeLayout>

这是结果:

如您所见,工具栏延伸到状态栏和硬件按钮之上。我不知道我是否正确地处理了这个问题。我错过了什么吗?

编辑

这就是我删除时相同视图的样子

getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

【问题讨论】:

【参考方案1】:

对于仍然遇到此问题的任何人,请执行以下操作。这只是解决了发布的问题的一半,即黑色状态栏

将以下主题添加到 res/value-v21/style

<style name="DialogTheme" parent="@style/Base.Theme.AppCompat.Light.Dialog">
     <item name="android:windowTranslucentStatus">true</item>
</style>

然后在DialogFragment 上应用样式onCreate

@Override
public void onCreate(@Nullable Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogTheme);

编辑 如果您的对话主题有问题,请使用此样式,例如colorAccentcolorControlHighlight

<style name="DialogTheme" parent="@style/ThemeOverlay.AppCompat.Dialog">
     <item name="android:windowTranslucentStatus">true</item>
</style>

【讨论】:

这救了我!将 android:windowTranslucentStatus 设置为 true 就可以了,疯狂【参考方案2】:

尝试在您的应用中使用相同的样式。我用没有片段的简单对话框进行了测试,效果很好。 像这样:

new Dialog(context, R.style.CardDetailsDialogStyle);

【讨论】:

什么是“CardDetailsDialogStyle”? @ThangBA CardDetailsDialogStyle 是应用于活动的样式【参考方案3】:

就我而言,SYSTEM_UI_FLAG_LAYOUT_STABLE 解决了重叠问题

        int width = ViewGroup.LayoutParams.MATCH_PARENT;

        int height = ViewGroup.LayoutParams.MATCH_PARENT;

        dialog.getWindow().setLayout(width,height);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            dialog.getWindow().setStatusBarColor(getResources().getColor(R.color.darkGrayTransp));
            dialog.getWindow().getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);//solves issue with statusbar
            dialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL| Gravity.TOP);
        

【讨论】:

这个解决方案对我有用......没有行 dialog.getWindow().getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);谢谢!!【参考方案4】:

您必须设置 fitsystemwindows = true。另一种方法是添加一个 0dp 的空间,并在对话框显示时将其高度更改为 25dp。

要更改空间大小,请使用布局参数,查看此帖子:How to create a RelativeLayout programmatically with two buttons one on top of the other?

【讨论】:

可能是对话框的高度小于工具栏。 我没关注,能详细点吗? 在 appcompat 21 for lollipop 中,您可以在 xml 中设置海拔高度。如果您使用的是工具栏,它可能比对话框具有更高的高度。 感谢工作!这是一些文档:developer.android.com/reference/android/view/…【参考方案5】:
<style name="DialogTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowIsFloating">false</item>
    </style>

【讨论】:

以上是关于带有半透明状态栏的全屏 DialogFragment的主要内容,如果未能解决你的问题,请参考以下文章

带有黑色半透明状态栏的 iPhone 上的 Web 应用程序:视口高度似乎是错误的

从没有状态栏的全屏视图到有状态栏的正常视图的错误翻转转换

带有半透明导航栏的滚动条

Android 5.0 半透明状态栏

在整个应用程序中添加带有搜索栏的半透明背景视图控制器

带有透明状态栏的 Android ScrollView 裁剪底部