DialogFragment中的ActionBar

Pau*_*ing 46 android android-dialogfragment android-actionbar

在我的Galaxy Tab 10.1上的日历应用程序中,创建新事件时,标题栏/操作栏区域中会出现一个对话框,其中包含完成和取消按钮.

在此输入图像描述

我想在我的应用中实现这一点.我已经尝试使用setHasOptionsMenu(true)除了覆盖onCreateOptionsMenu我的DialogFragment子类,但我的动作项目没有出现.我也试过getDialog().getActionBar()从内部打电话,onCreateView但总是回来null.

如果我开始一个Activity而不是显示一个对话但是占据了整个屏幕,我能够正常工作.是否有标准的方法来使用DialogFragment

Str*_*ero 86

使用谷歌小组帖子的想法,我能够将其设计成一项活动.您可能希望将高度和宽度修改为您选择的"动态"尺寸.然后设置您想要的任何ActionBar按钮

<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>
Run Code Online (Sandbox Code Playgroud)

-

public static 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.height = 850; //fixed height
    params.width = 850; //fixed width
    params.alpha = 1.0f;
    params.dimAmount = 0.5f;
    activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); 
    setContentView(R.layout.activity_main);
}
Run Code Online (Sandbox Code Playgroud)

  • 你刚刚丰富了我的应用程序! (3认同)
  • 我使用了一个自定义对话框,它不想显示我的操作栏图标,除非我使用了 android.R.style.Theme_*_DialogWhenLarge 样式(这使我的手机上的对话框全屏显示)。在自定义样式中使用 &lt;item name="android:windowIsFloating"&gt;false&lt;/item&gt; 并设置 myDialog.requestWindowFeature(Window.FEATURE_ACTION_BAR); 解决了,不需要别的了。感谢这篇文章! (2认同)

nag*_*ya0 14

如果您使用的是ActionBarSherlock,请将主题声明如下:

<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>
Run Code Online (Sandbox Code Playgroud)

并且,根据Luke Sleeman的回答,用PopupTheme 初始化SherlockActivity.

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);
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述


小智 11

在StrikeForceZero和Luke Sleeman实施建议的解决方案时遇到了一些麻烦,所以我想贡献自己的经验.我确信我只缺少一些东西,所以反馈会非常感激.

我做的是以下内容:

  1. 使用提供的PopupTheme创建样式,直接复制/粘贴:

    <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>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将showAsPopup()方法添加为片段中的方法,该方法将打开伪对话片段,直接复制/粘贴:

    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);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用简单的new()调用创建新活动的实例,然后将其传递给showAsPopup()方法:

    DialogTestActivity test = new DialogTestActivity();
    showAsPopup(test);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 为了测试的目的(我只是想确认我可以打开一个活动,显示为带有操作栏的对话框)我使用了一个非常简单的测试,直接从按钮视图api演示中窃取(用于布局文件) ,请参阅api演示中的buttons_1.xml):

    public class DialogTestActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.buttons_test);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

不幸的是,每次我尝试这个时,我都会在第一次调用activity.requestWindowFeature(Window.FEATURE_ACTION_BAR)时得到一个未指定的空指针异常;

04-29 16:39:05.361: W/System.err(15134): java.lang.NullPointerException
04-29 16:39:05.361: W/System.err(15134):    at android.app.Activity.requestWindowFeature(Activity.java:3244)
04-29 16:39:05.371: W/System.err(15134):    at packagenameremovedforlegalreasons.classname.showAsPopup(classname.java:602)
04-29 16:39:05.371: W/System.err(15134):    at packagenameremovedforlegalreasons.classname.onMapLongClick(classname.java:595)
04-29 16:39:05.371: W/System.err(15134):    at com.google.android.gms.maps.GoogleMap$5.onMapLongClick(Unknown Source)
04-29 16:39:05.371: W/System.err(15134):    at com.google.android.gms.internal.k$a.onTransact(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at android.os.Binder.transact(Binder.java:310)
04-29 16:39:05.381: W/System.err(15134):    at com.google.android.gms.maps.internal.IOnMapLongClickListener$Stub$Proxy.onMapLongClick(IOnMapLongClickListener.java:93)
04-29 16:39:05.381: W/System.err(15134):    at maps.i.s.a(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.y.v.d(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.y.bf.onLongPress(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.d.v.onLongPress(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.d.h.c(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.d.h.c(Unknown Source)
04-29 16:39:05.381: W/System.err(15134):    at maps.d.j.handleMessage(Unknown Source)
04-29 16:39:05.391: W/System.err(15134):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-29 16:39:05.391: W/System.err(15134):    at android.os.Looper.loop(Looper.java:137)
04-29 16:39:05.391: W/System.err(15134):    at android.app.ActivityThread.main(ActivityThread.java:5041)
04-29 16:39:05.391: W/System.err(15134):    at java.lang.reflect.Method.invokeNative(Native Method)
04-29 16:39:05.391: W/System.err(15134):    at java.lang.reflect.Method.invoke(Method.java:511)
04-29 16:39:05.391: W/System.err(15134):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-29 16:39:05.391: W/System.err(15134):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-29 16:39:05.391: W/System.err(15134):    at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

从堆栈跟踪中可以看出,预期的行为是在GoogleMap实例上长按打开窗口(使用API​​ 2中的MapFragments).所以我的第一个想法是尝试从片段中打开时出现了问题,因此我将调用传递回拥有的Activity.相同的错误,同样没有其他信息.

我在这一点上最好的猜测是new()调用没有充分实例化类/视图以便调用它来修改它的视图.事实证明,这似乎至少在某种程度上是正确的,因为将视图修改代码迁移到活动中,只需以正常方式打开活动即可:

通话活动:

    public void openMapDialog()
    {
        Intent intent = new Intent(this, DialogTestActivity.class);
        startActivity(intent);
    }
Run Code Online (Sandbox Code Playgroud)

新类代码:

    public class DialogTestActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // From: https://stackoverflow.com/questions/11425020/actionbar-in-a-dialogfragment
        this.requestWindowFeature(Window.FEATURE_ACTION_BAR);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        LayoutParams params = this.getWindow().getAttributes(); 
        params.alpha = 1.0f;
        params.dimAmount = 0f;
        this.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); 

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

        setContentView(R.layout.buttons_test);
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以我想我发布这一切的重点是澄清如果你想做上述海报建议的内容,你不能只是new()一个活动并调用showAsPopup().这可能是我对Android显示的缺乏经验,但是虽然这看起来有点显而易见,但是将showAsPopup()解释为当前视图调用,而不是正在创建的视图,因为您传入活动实例(这也只是这个,如果它应该在的onCreate()就像我终于实现了做).

因此,如果打算在创建活动中调用showAsPopup()而不是创建活动,那么在调用onCreate()之前如何获取可修改的Activity实例并不明显.问题是你在调用setContentView()之后不能调用requestWindowFeature()之类的东西(例子),这是一个问题,因为它通常在onCreate()中调用.

同样,如果有一个简单/更好的方法来做到这一点,我会非常感谢反馈.希望这对想要使用这种方法的人有所帮助.