6

Mi rivolgo a un'app per Android all'API 15 e al minimo 8. Quindi utilizzo la libreria di supporto per gestire i frammenti. Ho una serie di frammenti che uso in diverse parti dell'app.Aggiungere un frammento come intestazione ListView

Ora, in un'attività Ho un ListView nel layout:

<ListView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/listOfEvents" 
    android:layout_width="match_parent" android:layout_height="match_parent"> 
</ListView> 

vorrei aggiungere un frammento del mio nell'intestazione ListView. Ho provato questo:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.event_open); 

    listOfEvents = (ListView) findViewById(R.id.listOfEvents); 

      Fragment fragment = new SortingStandardFragment(); 
      getSupportFragmentManager() 
       .beginTransaction() 
        .add(fragment, null) 
       .commit(); 

      View fragmentView = fragment.getView(); // problem: fragment is null! 
      listOfEvents.addHeaderView(fragmentView); 
    } 

ma ottengo un errore dal fragment.getView() restituisce il valore null (documentazione di riferimento API dire che devo mettere un GroupView Id nella chiamata aggiuntivo, ma dove dovrebbero ho messo il GroupView in ? il layout c'è un altro modo di colpire nel segno

+0

Non sono sicuro che questo può funzionare in questo modo, ma l'idea del frammento sta creando un framelayout impostando un id (puoi creare id aggiungendo il nome id nelle risorse), aggiungere come intestazione e quindi effettuare una transazione sostituendo quell'id con il frammento – sherpya

risposta

14

ho risolto questo con la creazione di un nuovo layout che contiene solo il frammento che ho bisogno nell'intestazione lista:?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <fragment 
     android:id="@+id/myFragmentEmbedded" 
     android:name=".SortingStandardFragment" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

e nel codice di attività:

LayoutInflater inflater = getLayoutInflater(); 
header = inflater.inflate(R.layout.myLayout, null); 
listOfEvents.addHeaderView(header); 

SortingStandardFragmenttitleFragment = (SortingStandardFragment) 
    getSupportFragmentManager() 
      .findFragmentById(R.id.myFragmentEmbedded); 
4

Volevo una versione senza dover ricorrere a un altro file XML, così qui va:

Fragment fragment = ... 
FrameLayout v = new FrameLayout(getActivity()); 
v.setId(42); 
listView.addHeaderView(v, null, false); 
FragmentManager fm = getActivity().getSupportFragmentManager(); 
fm.beginTransaction().add(v.getId(), fragment).commit(); 
+8

è meglio dichiarare l'id nel file ids.xml, tuttavia, per assicurarsi che non vi siano rischi di sovrapposizione degli ID. – njzk2

+0

se si aggiunge il contenitore di intestazione a ListView non in onCreate (supposto dopo richiesta), l'app si arresta in modo anomalo su onBackPressed() perché listview distrugge child (il contenitore dell'intestazione) dopo l'arresto - frammentmanager non inserisce il frammento nel contenitore – merovingen

1

Nel caso in cui qualcuno è curioso il motivo per cui il suo primo tentativo è fallito:

  • ciclo di vita gli eventi sono registrati nell'interfaccia utente
  • Fragment.onCreateView è un evento del ciclo di vita
  • Activity.onCreate è un ciclo di vita evento
  • .getView() restituisce la vista creata in Fragment.onCreateView
  • commit inviare un evento del ciclo di vita

Conclusione: il risultato di commit è visibile dal prossimo ciclo che è dopo onCreate restituiti.

Si potrebbe provare a forzare commit per essere immediati con getSupportFragmentManager().executePendingTransactions(), dopo aver letto la documentazione su di esso.

Problemi correlati