【问题标题】:How to make DialogFragment fullscreen without overlapping status bar/navigation bar and mantain status bar color?如何使DialogFragment全屏不重叠状态栏/导航栏并保持状态栏颜色?
【发布时间】:2016-12-10 04:02:37
【问题描述】:

我已经在谷歌上搜索了几个小时并尝试了无数的东西,但我就是无法让它工作......

这是MyFragment.java

public class MyFragment extends DialogFragment {

    public MyFragment() {
        // Required empty public constructor
    }

    public static MyFragment newInstance() {
        MyFragment newFragment = new LoginDialogFragment();
        newFragment.setCancelable(false);
        return newFragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new Dialog(getActivity(), R.style.MyAppTheme_Dialog);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        Window window = getDialog().getWindow();

        if (window != null) {
            window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
            window.setWindowAnimations(R.style.MyAppTheme_Dialog);
        }
    }

}

这是styles.xml

<style name="MyAppTheme" parent="PreferenceFixTheme.Light.NoActionBar">
    <item name="android:windowBackground">@color/background</item>
    <item name="android:colorBackground">@color/background</item>
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="preferenceCategory_marginBottom">0dp</item>
</style>

<style name="MyAppTheme.Dialog">
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowBackground">@null</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>

这几乎可以按我的预期工作......唯一的问题是调用window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); 来填充整个屏幕(减去状态/导航栏)会将状态栏颜色更改为黑色。当我关闭对话框时,它变回colorPrimaryDark

如果我删除 window.setLayout(...) 行,状态栏将保留 colorPrimaryDark,但对话框大小将是默认值(屏幕中间的一个小方块)。

在我调用window.setLayout(...) 的同一个地方,我尝试输入以下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    getWindow().setStatusBarColor(ContextCompat.getColor(getActivity, R.color.primary_dark));
}

这会将状态栏颜色设置为colorPrimaryDark,但它会与状态栏和导航栏重叠。

如果不重叠状态栏和导航栏并在状态栏上保留colorPrimaryDark,我无法获得全屏。

我发现了一些与相同问题相关的问题,但我无法让建议发挥作用。两者都没有公认的答案:

【问题讨论】:

  • 必须是DialogFragment吗? Activity 会起作用吗?
  • 您是否尝试过覆盖对话框片段。我有代码。我不知道哪个会满足您的需求。任何方式我都会发布代码。试试看。
  • 你为什么要强制一个对话框不是一个对话框?您似乎使用了错误的抽象。
  • @Karakuri 它必须是DialogFragment,因为我需要setCancelable(false) 在打开此特定片段时禁止按下后退按钮。要在普通片段上执行此操作,需要在 Activity 上处理后退按钮按下,我不喜欢可能的解决方案。
  • @ianhanniballake 从我们的 UX/UI 团队的角度来看,这是一个对话框,它只是填满了整个屏幕(这是他们的模态对话框方法)。这不是应该在屏幕上长期存在的东西。您打开它,快速执行片段应执行的操作并关闭它,而不会弄乱当前的活动/片段生命周期。

标签: java android android-dialogfragment android-statusbar


【解决方案1】:

检查这个定制的对话框片段,试试它会满足你的需要。并告诉我。

 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.util.TypedValue;
 import android.view.Display;

/**
  * Created by Noorul on 02-07-16.
*/

public class _DialogFragment extends DialogFragment {
  @Override
  public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
  //   preventScreenRotation();
  }

  @Override
  public void onDestroy() {
    // releaseScreenRotation();
    super.onDestroy();
}

@SuppressWarnings("deprecation")
@Override
public void onStart() {
    super.onStart();

    // change dialog width
    if (getDialog() != null) {

        int fullWidth = getDialog().getWindow().getAttributes().width;
        int fullHeight = getDialog().getWindow().getAttributes().height;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            Display display =    getActivity().getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);

            fullWidth = size.x;
            fullHeight = size.y;
        } else {
            Display display = getActivity().getWindowManager().getDefaultDisplay();
            fullWidth = display.getWidth();
            fullHeight = display.getHeight();
        }

        final int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources()
                .getDisplayMetrics());

        int w = fullWidth - padding;
        int h = fullHeight - (padding * 2);

        getDialog().getWindow().setLayout(w, h);
    }
}


 private void preventScreenRotation() {
     if (getResources().getConfiguration().orientation ==  Configuration.ORIENTATION_PORTRAIT) {
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
     } else {  
      getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
  }

  private void releaseScreenRotation() {
      getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}

根据您的需要更改对话框的大小。

【讨论】:

  • 这几乎奏效了......我忘了提及我的问题的一个细节。我在这个片段上有一个向上滑动的动画(从下到上),这个代码片段的大小将完全符合我的预期,状态栏将保持它的颜色。唯一的问题是片段在向上滑动时将位于底部导航栏的顶部...... :(
  • 你能把截图分享给我吗?
  • 我看不出实际的屏幕截图是否尚未发布,但它与此非常相似:i.stack.imgur.com/cppoj.png - 看看“写评论”位如何与导航栏按钮重叠?这就是幻灯片动画期间发生的情况。完成后,它将如下所示(但状态栏颜色正确):i.stack.imgur.com/HiSv9.png - 这就是我想要的。
  • 你能贴出对话框的 XML 代码吗?尝试从顶部添加填充。它会有所帮助
  • 我不明白顶部填充将如何帮助动画与底部导航栏重叠...
【解决方案2】:

根据材料设计指南创建全屏对话框。 把这段代码放在DialogFragment中:

 @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }

通过以下方式调用此对话框:

getSupportFragmentManager().beginTransaction().add(android.R.id.content, FullScreenDialog.newInstance()).addToBackStack(null).commit();

在基本布局中将上边距设置为 24dp。这样对话框就不会与状态栏重叠。

【讨论】:

    猜你喜欢
    • 2015-08-03
    • 2013-02-04
    • 2023-04-09
    • 1970-01-01
    • 2018-03-03
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多