ActionBar in a DialogFragment

2019-01-04 16:19发布

In the Calendar app on my Galaxy Tab 10.1, when creating a new event a dialog comes up with Done and Cancel buttons in the title bar/action bar area.

enter image description here

I'd like to implement this in my app. I've tried using setHasOptionsMenu(true) in addition to overriding onCreateOptionsMenu in my DialogFragment subclass, but my action items do not appear. I've also tried calling getDialog().getActionBar() from within onCreateView but it always returns null.

I am able to get this working if I start an Activity rather than showing a dialog but that takes up the whole screen. Is there a standard way to do this using a DialogFragment?

8条回答
再贱就再见
2楼-- · 2019-01-04 17:12

I have spent an incredible amount of time playing around with this. The accepted answer works on a galaxy nexus 7 (Android 4.2), but fails on a samsung galaxy SIII (Android 4.1) and a samsung galaxy tab 10.2 (Android 4.0), with the following exception:

IllegalStateException: ActionBarView can only be used with android:layout_width="match_parent" (or fill_parent)

This is caused by code in ActionBarView.onMeasure(int, int) which checks to ensure the layout is set to match_parent. The correct solution is instead set the width of the window via setLayout instead of using the setAttributes.

This is a fixed version of showAsPopup() which works on all devices I have tested under:

private void showAsPopup(Activity activity) {
    //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
    activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
    activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
            WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    LayoutParams params = activity.getWindow().getAttributes(); 
    params.alpha = 1.0f;
    params.dimAmount = 0f;
    activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); 

    // This sets the window size, while working around the IllegalStateException thrown by ActionBarView
    activity.getWindow().setLayout(850,850);
}

For completeness sake, here is the PopupTheme again:

<style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog">
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowSoftInputMode">stateAlwaysHidden</item>
    <item name="android:windowActionModeOverlay">true</item>
    <item name="android:windowIsTranslucent">true</item>
</style>
查看更多
Evening l夕情丶
3楼-- · 2019-01-04 17:13

If you are using ActionBarSherlock, declare the theme as below:

<style name="PopupTheme" parent="Theme.Sherlock">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateAlwaysHidden</item>
    <item name="android:windowActionModeOverlay">true</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowCloseOnTouchOutside">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="windowContentOverlay">@null</item>
</style>

And, initialize a SherlockActivity with PopupTheme according to Luke Sleeman's answer.

private void showAsPopup(SherlockActivity activity) {
    //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
    //activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); // NO NEED to call this line.
    activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
            WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    LayoutParams params = activity.getWindow().getAttributes(); 
    params.alpha = 1.0f;
    params.dimAmount = 0.5f;
    activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); 

    // This sets the window size, while working around the IllegalStateException thrown by ActionBarView
    activity.getWindow().setLayout(width,height);
}

Result:

enter image description here

查看更多
登录 后发表回答