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

22

我有一个DialogFragment,我想将其显示为全屏。但我仍希望StatusBar和底部的硬件按钮存在。我还想设置StatusBar的背景颜色(适用于Lollipop)。

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

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

状态栏和硬件键盘变为半透明,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_width="match_parent"
android:layout_height="match_parent"
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_height="wrap_content"
    android:layout_width="match_parent"
    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_height="wrap_content"
        android:layout_width="match_parent">

        All subview elements here...

    </ScrollView>

</RelativeLayout>

这是结果:屏幕截图

正如您所见,工具栏横跨状态栏和硬件按钮。我不知道我的方法是否正确。我有什么遗漏吗?

编辑

当我删除时,相同的视图看起来像:

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

enter image description here

6个回答

7
在我的情况下,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);
        }

1
这个解决方案对我有用... 没有这一行代码 dialog.getWindow().getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE); 谢谢!! - MauroAlexandro

7

如果你仍然遇到这个问题,请按照以下步骤操作。这只解决了所发布的问题的一半,即黑色状态栏。

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

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

然后在onCreate中对DialogFragment应用样式。

@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>

enter image description here


这个救了我!将 android:windowTranslucentStatus 设置为 true 即可解决问题,太神奇了。 - Bruce

5

尝试使用与您的应用相同的样式。我测试了简单对话框而没有片段,效果良好。

像这样:

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

什么是“CardDetailsDialogStyle”? - Thang BA
@ThangBA CardDetailsDialogStyle是应用于活动的样式。 - Kishan Vaghela

2

也许对话框的高度小于工具栏。 - JavierSegoviaCordoba
我不是很明白,您能否详细解释一下? - pnit
在Lollipop的AppCompat 21中,您可以在XML中设置高度。如果您正在使用工具栏,它可能比对话框具有更高的高度。 - JavierSegoviaCordoba
谢谢,那个起作用了!这里有一些文档:http://developer.android.com/reference/android/view/View.html#setFitsSystemWindows(boolean) - toidiu

0
只需将android:fitsSystemWindows="true"应用于您的根ViewGroup即可:
`<FrameLayout

android:fitsSystemWindows="true">

<View .../>

0
<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接