46

Galaxy Tab 10.1 のカレンダー アプリで、新しいイベントを作成すると、ダイアログのタイトル バー/アクション バー領域に [完了] ボタンと [キャンセル] ボタンが表示されます。

ここに画像の説明を入力

これをアプリに実装したいと思います。サブクラスでオーバーライドにsetHasOptionsMenu(true)加えて使用しようとしましたが、アクション アイテムが表示されません。内部からの呼び出しも試みましたが、常に返されます。onCreateOptionsMenuDialogFragmentgetDialog().getActionBar()onCreateViewnull

Activityダイアログを表示するのではなく、開始すると、これを機能させることができますが、それは画面全体を占有します。を使用してこれを行う標準的な方法はありDialogFragmentますか?

4

8 に答える 8

86

Google グループの投稿からのアイデアを使用して、アクティビティのスタイリングを行うことができました。高さと幅を、できれば選択した「動的」サイズに変更することをお勧めします。次に、必要な 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>

--

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);
}
于 2012-09-05T05:31:40.997 に答える
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>

そして、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);
}

結果:

ここに画像の説明を入力してください

于 2013-03-04T16:22:20.157 に答える
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>
    
  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);
    }
    
  3. シンプルな new() 呼び出しを使用して新しいアクティビティのインスタンスを作成し、それを showAsPopup() メソッドに渡します。

    DialogTestActivity test = new DialogTestActivity();
    showAsPopup(test);
    
  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);
        }
    }
    

残念ながら、これを試すたびに、最初の呼び出し activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); で未指定の null ポインター例外が発生します。

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)

スタック トレースからわかるように、意図した動作は、GoogleMap インスタンスを長押ししてウィンドウを開くことです (API 2 の MapFragments を使用)。したがって、最初に考えたのは、Fragment から開こうとしたことに問題があるということでした。そのため、呼び出しを所有する Activity に戻しました。同じエラー、追加情報なし。

この時点での私の最善の推測は、ビューを変更するための呼び出しを行うために、 new() 呼び出しがクラス/ビューを十分にインスタンス化していないということでした。ビュー変更コードをアクティビティに移行し、通常の方法でアクティビティを開くだけで機能するため、これは少なくともある程度は正しいように見えます。

通話アクティビティ:

    public void openMapDialog()
    {
        Intent intent = new Intent(this, DialogTestActivity.class);
        startActivity(intent);
    }

新しいクラス コード:

    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);
        }
    }

したがって、これをすべて投稿するポイントは、上記のポスターが示唆することを実行したい場合は、アクティビティを単に new() して showAsPopup() を呼び出すことはできないことを明確にすることだと思います。これは私の Android の表示経験不足かもしれませんが、これは少し明白に思えますが、作成中のビューではなく、現在のビューによって呼び出されているものとして showAsPopup() を解釈するのも当然のようです。これは、アクティビティ インスタンスを渡しているためです。 (私がやったように onCreate() で行われるはずだった場合、これはちょうどこれになります)。

そのため、作成されたアクティビティではなく作成中のアクティビティで showAsPopup() を呼び出すことが意図されている場合、 onCreate() が呼び出される前に変更可能な Activity インスタンスを取得する方法は明らかではありません。問題は、setContentView() が呼び出された後に requestWindowFeature() などを呼び出すことができないことです ( example )。これは、通常 onCreate() で呼び出されるため問題です。

繰り返しますが、これを行うための簡単でより良い方法があれば、フィードバックをいただければ幸いです。このアプローチを使用したい人にとって、これが役立つことを願っています。

于 2013-04-29T21:58:39.927 に答える
4

私はこれで遊ぶのに信じられないほどの時間を費やしました。受け入れられた回答は、galaxy nexus 7 (Android 4.2) では機能しますが、samsung galaxy SIII (Android 4.1) および samsung galaxy tab 10.2 (Android 4.0) では失敗しますが、次の例外があります。

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

これは、レイアウトが match_parent に設定されていることを確認するActionBarView.onMeasure(int, int) のコードが原因です。正しい解決策は、setAttributes を使用する代わりに、setLayout を使用してウィンドウの幅を設定することです。

これは、私がテストしたすべてのデバイスで動作する 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);
}

完全を期すために、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>
于 2013-02-11T10:40:21.367 に答える
1

Veeti が暗示したように、ダイアログ テーマを使用してアクティビティを実装してみてください。Android マニフェスト:

<activity android:name=".YourActivity" android:theme="@android:style/Theme.Dialog </activity>

うまくいけば、それは役に立ちます。

于 2012-07-11T03:27:56.827 に答える
1

私はおそらくその経験はありませんが、アクティビティを使用し、アクションバーの項目を追加してから:

<activity android:name=".YourActivity" android:theme="@android:style/Theme.Holo.Light.Dialog" />

それが役立つことを願っています!

于 2012-07-11T04:01:12.567 に答える
0

本当の答えではないことはわかっていますが、上記のソリューションは非常に洗練されていないように見えるため、.noActionBar を使用してダイアログ テーマを何かから継承し、パネルの上部にビューを作成するなど、アクション バーをまったく回避する方が簡単だと考えるかもしれません。アクションバーを模倣するもので、少なくともこの方法ではすべて xlm にとどまります。

于 2014-10-20T01:18:51.497 に答える