ActionBar in un DialogFragment

Nel Calendario app sul mio Galaxy Tab 10.1, quando si crea un nuovo evento di un dialogo con pulsanti Fatto e Annulla nella barra del titolo di azione/zona bar.

ActionBar in un DialogFragment

Vorrei implementare nel mio app. Ho provato con setHasOptionsMenu(true) oltre l’override di onCreateOptionsMenu nel mio DialogFragment sottoclasse, ma la mia azione elementi non vengono visualizzati. Ho anche provato a chiamare getDialog().getActionBar() dall’interno onCreateView ma restituisce sempre null.

Sono in grado di ottenere questo lavoro se inizio un Activity piuttosto che mostrare una finestra di dialogo, ma che occupa l’intero schermo. C’è un modo standard per fare questo, utilizzare una DialogFragment?

  • Questo è probabilmente un’attività in stile a guardare come un dialogo invece di un “vero dialogo”.
  • “le novità più recenti vengono aggiunti alla libreria di supporto versione della Barra degli strumenti, e sono disponibili su qualsiasi dispositivo in grado di utilizzare la libreria di supporto. Per questo motivo, è necessario utilizzare la libreria di supporto della Barra degli strumenti di classe per implementare le attivita’ di bar app.” developer.android.com/training/appbar/setting-up

 

8 Replies
  1. 86

    utilizzando l’idea da un google gruppi post sono stato in grado di tirare fuori styling un’attività. si desidera modificare l’altezza e la larghezza di una “dinamica” la dimensione della vostra scelta di preferenza. Quindi impostare qualsiasi ActionBar pulsanti che si vorrebbe

    <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);
    }
    • Hai salvato la mia giornata(s)!
    • Appena arricchito la mia applicazione da un SACCO!
    • Sembra che la finestra di dialogo actionbar non ottiene stile personalizzato. Si ottiene lo stile di default. Qualsiasi idea di come fare la actionbar hanno personalizzato stile?
    • mi dispiace per la (MOLTO) in ritardo di risposta. Questo codice -non – dare stile/tema nelle domande immagine di esempio. Si dovrebbe creare un tema molto simile a jgilfelt.github.io/android-actionbarstylegenerator Allora Si potrebbe avere per dichiarare il tema in ogni res/values-XX/syles.xml se si sta ancora ricevendo il default tema holo.
    • Io uso una finestra di Dialogo personalizzata che non voglio mostrare la mia azione icona della barra a meno che non ho usato un android.R.stile.Theme_*_DialogWhenLarge stile (che ha la finestra a schermo intero sul mio telefono). Utilizzando <item name=”android:windowIsFloating”>false</item> in stile personalizzato e impostazione myDialog.requestWindowFeature(Finestra.FEATURE_ACTION_BAR); risolto, senza necessità di altro. Grazie per questo post!
    • Vorrei ottenere lo stesso ma io sono confuso: Dove devo inserire il showAdPopup Methode? Qual è il parametro attività? È questa un’attività che dovrebbe visualizzato come comparsa o è l’attività che dovrebbero mostrare un frammento come popup?
    • Ho avuto la stessa domanda. Vedere user1475907 la risposta qui sotto. È necessario creare le Attività tramite un Intent (non dimenticare di aggiungere il tuo AndroidManifest file) e hanno il onCreate(...) chiamata al metodo showAsPopup() (è possibile omettere il parametro e l’uso this, in quanto è un metodo della stessa classe di Attività) immediatamente dopo la super.onCreate(...) chiamata.
    • Chiunque può verificare questo funziona ancora in fase di API 21/lecca-lecca? Ho appena ottenere uno sfondo nero dove dovrebbe essere oscurato.
    • penso che deve essere activity.setContentView(R.layout.activity_main);

  2. 14

    Se si utilizza ActionBarSherlock, dichiarare il tema, così come di seguito:

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

    E, inizializzare un SherlockActivity con PopupTheme secondo Luca Sleeman risposta.

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

    Risultato:

    ActionBar in un DialogFragment

  3. 11

    Avuto alcuni problemi nell’implementare le soluzioni suggerite da StrikeForceZero e Luca Sleeman, così ho voluto contribuire con la mia esperienza. Sono sicuro che c’è qualcosa che mi manca in modo di feedback sarebbe molto apprezzato.

    Cosa che ho fatto è stato il seguente:

    1. Creare uno stile utilizzando i PopupTheme, diritto di copia/incolla:

      <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. Aggiungere il showAsPopup() metodo come metodo nel frammento che avrebbe aperto il falso frammento di dialogo, diritto di copia/incolla:

      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. Creare un’istanza della nuova attività utilizzando un semplice nuovo() la chiamata, e poi passare ai showAsPopup() metodo:

      DialogTestActivity test = new DialogTestActivity();
      showAsPopup(test);
    4. Per lo scopo del test (stavo solo cercando di confermare che potevo aprire un’attività che si presenta come una finestra di dialogo con una action bar) ho usato una semplicissima prova, rubato direttamente dal pulsante di vista api demo (per i file di layout, vedere buttons_1.xml nell’api demo):

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

    Purtroppo, ogni volta che ho provato questo, ho un non meglio specificato puntatore null eccezione alla prima chiamata, attività.requestWindowFeature(Finestra.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)

    Come si può vedere dalla traccia dello stack, il comportamento previsto è di aprire la finestra su un premere a lungo su un GoogleMap istanza (utilizzando il MapFragments da API 2). Quindi il mio primo pensiero è stato che c’era un problema dal tentativo di aprire da un Frammento, così ho passato la chiamata per proprietario di Attività. Stesso errore, lo stesso non vi sono ulteriori informazioni.

    La mia ipotesi migliore a questo punto era che un nuovo() chiamata non sufficientemente creare un’istanza della classe/view per fare le chiamate a modificare la sua vista. Scopre che questo sembra essere almeno un po ‘ vero, come la migrazione di vista la modifica del codice in attività e semplicemente aprendo l’attività in modo normale opere:

    Chiamata di attività:

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

    Nuovo codice della classe:

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

    Quindi credo che il punto di me di postare tutto questo per chiarire che se si vuole fare quello di cui sopra manifesti suggeriscono, non si può semplicemente new() un’attività e chiamare showAsPopup(). Questa potrebbe essere la mia inesperienza con Android mostrando attraverso, ma mentre questo sembra un po ‘ ovvio, sembra anche naturale interpretare showAsPopup() come essere chiamati dalla vista corrente, non è la vista che viene creato, come stai passando l’istanza di attività (che sarebbe solo essere questo se doveva essere fatto in onCreate() come ho fatto io).

    Quindi, se l’intenzione è quella di chiamare showAsPopup() in creazione di attività e non la creato attività, non è ovvio come per ottenere l’istanza di Attività che è modificabile prima dell’onCreate() di essere chiamato. Il problema è che non si possono chiamare le cose come requestWindowFeature() dopo la chiamata a setcontentview() è chiamato (esempio), che è un problema dal momento che di solito è in onCreate().

    Ancora una volta, se vi è un facile/modo migliore per fare questo, sarei molto lieto di feedback. Speriamo che questo sia utile per le persone che vogliono utilizzare questo approccio.

    • Grazie, che mi ha aiutato. Il mio modo di affrontare il problema era di cambiare showAsPopup(Activity activity) metodo per una “public static” metodo e quindi chiamare dal onCreate prima di ogni altra cosa (tranne super.onCreate.
    • Grazie per spiegare dove si trova l’originale risposta non riesce. Nota Niak che non c’è bisogno per il tuo metodo statico.
    • Grande spiegazione!!! Due cose che possono ancora essere fonte di confusione: Nel punto 2, si sta scrivendo su FRAMMENTI. Dovrebbe essere chiaro che un’ATTIVITÀ a un’altra ATTIVITÀ. Non ci sono Frammenti coinvolti. Inoltre il tema della DialogTestActivity deve essere impostato su @style/PopupTheme nel manifesto dell’App. Altrimenti il Dialogo Popup non viene visualizzato correttamente.
  4. 4

    Ho speso un’enorme quantità di tempo a giocare con questo. Accettato di rispondere lavora su un galaxy nexus 7 (Android 4.2), ma non su un samsung galaxy SIII (Android 4.1) e un samsung galaxy tab 10.2 (Android 4.0), con la seguente eccezione:

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

    Questo è causato dal codice in ActionBarView.onMeasure(int, int) che i controlli per garantire il layout è impostato per match_parent. La soluzione corretta è invece imposta la larghezza della finestra tramite setLayout invece di utilizzare il setAttributes.

    Questa è una versione fissa di showAsPopup() che funziona su tutti i dispositivi che ho provato sotto:

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

    Per completezza, ecco il PopupTheme di nuovo:

    <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>
  5. 1

    Come Veeti implicita, si può provare a realizzare un’Attività con una finestra di Dialogo in Tema. In Android Manifest:

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

    Spero che sarà di aiuto.

  6. 1

    Probabilmente non sono esperti in questo, ma vorrei usare un’attività, aggiungere l’azione delle voci della barra e poi :

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

    Speranza che aiuta!

    • Questo non si riuscirà a mostrare l’attività di ricerca come un dialogo, ma ancora nessuna barra di azione per essere visto. Ho provato anche avere un tema personalizzato che eredita da Theme.Holo.Light.Dialog e impostare il android:windowActionBar attributo true. Una volta che lo faccio, ho un eccezione java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layout.
  7. 1

    Ho trovato un bel modo per farlo , utilizza setCustomTitle su generatore di alertDialog per il DialogFragment (possibile anche il alertDialog stesso).

    public Dialog onCreateDialog(final Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(activity,...);
        final Toolbar toolbar = (Toolbar) inflater.inflate(R.layout.dialog_app_filter_toolbar, null, false);
        //<= prepare toolbar and dialog here
        return builder.create();
        }

    E il risultato (da la mia app ):

    ActionBar in un DialogFragment

    ActionBar in un DialogFragment

    Se non si desidera utilizzare AlertDialog, si può ancora mettere una barra degli strumenti nel vostro layout della finestra di dialogo e utilizzare.

  8. 0

    So che non è una vera risposta, ma soprattutto le soluzioni sembrano così poco elegante che si potrebbe pensare che sarebbe più facile per evitare la barra di azione, come ereditare la finestra di dialogo tema da qualcosa .noActionBar e quindi creare vista sulla parte superiore del pannello che imita la barra delle azioni, almeno in questo modo tutto rimane in xlm.

    • Se da poco elegante, è dire troppo hardcoded, qui si va: DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); getWindow().setLayout(metrics.widthPixels - 80, metrics.heightPixels - 80);

Lascia un commento