requestFeature () deve essere chiamato prima di aggiungere contenuti


135

Sto cercando di implementare una barra del titolo personalizzata:

Ecco la mia classe Helper:

import android.app.Activity;
import android.view.Window;

public class UIHelper {
    public static void setupTitleBar(Activity c) {
        final boolean customTitleSupported = c.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        c.setContentView(R.layout.main);

        if (customTitleSupported) {
            c.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
        }
    }
}

Ecco dove lo chiamo in onCreate ():

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setupUI();
}

private void setupUI(){
     setContentView(R.layout.main);
     UIHelper.setupTitleBar(this);
}

Ma ottengo l'errore:

requestFeature() must be called before adding content

Risposte:


331

Bene, fai solo quello che ti dice il messaggio di errore.

Non chiamare setContentView()prima requestFeature().

Nota:

Come detto nei commenti, per entrambi ActionBarSherlocke AppCompatbiblioteca, è necessario chiamare requestFeature()primasuper.onCreate()


60
accidenti, questa è una risposta di classe.
Una persona il

60
Per ActionBarSherlock, è anche necessario chiamare requestFeature()prima super.onCreate(). Riferimento: github.com/JakeWharton/ActionBarSherlock/issues/…
Saran,

1
Cosa succede se è necessario mostrare un layout senza una barra del titolo e quindi mostrarne uno con una barra del titolo? Dovrai usarlo requestWindowFeature(Window.FEATURE_NO_TITLE)per nasconderlo, quindi setContentView()per il tuo primo layout, quindi requestWindowFeature(Window.FEATURE_CUSTOM_TITLE)per mostrare di nuovo la barra del titolo. Sarebbe dopo setContentView()la seconda volta.
msbg

35
È lo stesso caso in AppCompat di @Saran. Devi chiamare il tuo requestFeatureprimasuper.onCreate()
Jaison Brooks il

7
Questa risposta non aiuta molto ... ma cosa ne so
Ojonugwa Jude Ochalifu,

23

So che ha più di un anno, ma chiamare requestFeature()non ha mai risolto il mio problema. In realtà non lo chiamo affatto.

Suppongo fosse un problema con il gonfiare il punto di vista. Nonostante tutta la mia ricerca, non ho mai trovato una soluzione adatta fino a quando non ho giocato con i diversi metodi per gonfiare una vista.

AlertDialog.Builder è la soluzione semplice ma richiede molto lavoro se si utilizza il onPrepareDialog()per aggiornare quella vista.

Un'altra alternativa è utilizzare AsyncTask per le finestre di dialogo.

Un'ultima soluzione che ho usato è di seguito:

public class CustomDialog extends AlertDialog {

   private View content;

   public CustomDialog(Context context) {
       super(context);

       LayoutInflater li = LayoutInflater.from(context);
       content = li.inflate(R.layout.custom_view, null);

       setUpAdditionalStuff(); // do more view cleanup
       setView(content);           
   }

   private void setUpAdditionalStuff() {
       // ...
   }

   // Call ((CustomDialog) dialog).prepare() in the onPrepareDialog() method  
   public void prepare() {
       setTitle(R.string.custom_title);
       setIcon( getIcon() );
       // ...
   }
}

* Alcune note aggiuntive:

  1. Non fare affidamento sul nascondere il titolo. Spesso c'è uno spazio vuoto nonostante il titolo non sia stato impostato.
  2. Non provare a creare la tua vista con il piè di pagina dell'intestazione e la vista centrale. L'intestazione, come indicato sopra, potrebbe non essere completamente nascosta nonostante la richiesta FEATURE_NO_TITLE.
  3. Non applicare uno stile eccessivo alla visualizzazione del contenuto con attributi di colore o dimensioni del testo. Lascia che la finestra di dialogo gestisca ciò, altrimenti sostieni il rischio di inserire il testo nero in una finestra di dialogo blu scuro perché il fornitore ha invertito i colori.

Inizialmente ho inserito setTitle () e setIcon () nel metodo onCreate (), ma la modifica lo ha spostato nel metodo Prepet () che viene chiamato durante il metodo onPrepareDialog ().
Cookster,

2
Grazie per la condivisione. Penso che la seguente riga content = inflater.inflate(R.layout.custom_view, null);dovrebbe essere probabilmente content = li.inflate(R.layout.custom_view, null);. Quindi, inflaterdeve essere sostituito da li.
Studente il

14

Stavo estendendo un DialogFragment e la risposta sopra non funzionava. Ho dovuto usare getDialog () per ottenere rimuovere il titolo:

getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);

@ojonugwaochalifu era qualche tempo fa, quindi non ricordo esattamente ma sono sicuro che deve essere fatto prima del metodo setcontentView ()
Argomento illegale

1
per chiunque abbia lo stesso problema: ho aggiunto questo codice in onViewCreated ();
7geeky

2

L'errore non ti dice esattamente cosa c'è che non va? Stai chiamando requestWindowFeaturee setFeatureIntdopo aver chiamato setContentView.

A proposito, perché chiami setContentViewdue volte?


2

Per SDK versione 23 e successive, viene generata la stessa RuntimeException se si utilizza AppCompatActivity per estendere l'attività. Non accadrà se la tua attività deriva direttamente dall'attività.

Questo è un problema noto su Google, come menzionato in https://code.google.com/p/android/issues/detail?id=186440

Per ovviare a ciò, utilizzare il metodo supportRequestWindowFeature () anziché utilizzare requestFeature ().

Si prega di votare se risolve il problema.


1

Cambia la versione di Compilare SDK , la versione di SDK di destinazione in Build Tools versione a 24.0.0 in build.gradle se riscontri problemi nella richiesta


0

Nel mio caso ho mostrato DialogFragmentin Activity. In questo frammento di dialogo ho scritto come in DialogFragment rimuovi bordo nero :

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_FRAME, 0)
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    super.onCreateDialog(savedInstanceState)

    val dialog = Dialog(context!!, R.style.ErrorDialogTheme)
    val inflater = LayoutInflater.from(context)
    val view = inflater.inflate(R.layout.fragment_error_dialog, null, false)
    dialog.setTitle(null)
    dialog.setCancelable(true)
    dialog.setContentView(view)
    return dialog
}

Rimuovere setStyle(STYLE_NO_FRAME, 0)in onCreate()o modificare / rimuovere onCreateDialog. Perché le impostazioni della finestra di dialogo sono cambiate dopo la creazione della finestra di dialogo.


0

Ho avuto questo problema con Dialogs basato su un DialogFragment esteso che funzionava bene su dispositivi con API 26 ma non funzionava con API 23. Le strategie precedenti non funzionavano ma ho risolto il problema rimuovendo il metodo onCreateView (che era stato aggiunto da un altro modello Android Studio recente) da DialogFragment e creazione della finestra di dialogo in onCreateDialog.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.