6

Dirijo una aplicación Android a la API 15 y al mínimo 8. De modo que utilizo la biblioteca de soporte para administrar fragmentos. Tengo un conjunto de fragmentos que utilizo en varias partes de la aplicación.Agregue un fragmento como encabezado ListView

Ahora, en una actividad que tienen un ListView en el diseño:

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

Me gustaría añadir un fragmento de la mina en la cabecera ListView. He intentado esto:

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

pero me sale un error ya fragment.getView() devuelve un valor nulo (documentos de referencia API decir que tengo que poner un Id GroupView en el llamado complemento, pero donde debo poner el GroupView en ? el diseño ¿hay otra manera de dar en el blanco

+0

No estoy seguro de que esto pueda funcionar de esta manera, pero la idea del fragmento es crear un framelayout estableciendo un id. (Puede hacer id agregando el nombre del id en los recursos), agregar como encabezado y luego hacer una transacción reemplazando ese id con el fragmento – sherpya

Respuesta

14

he resuelto mediante la creación de un nuevo diseño que contiene sólo el fragmento que necesito en la cabecera de 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> 

y en el código de actividad:

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

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

que quería una versión sin tener que recurrir a otro archivo XML, así que aquí 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

es mejor declarar el id en el archivo ids.xml, para asegurarse de que no haya riesgo de superposición de los identificadores. – njzk2

+0

si agrega el contenedor de encabezado a ListView no en onCreate (supuestamente después de la solicitud), su aplicación se bloquea en onBackPressed() porque listview destroy child (contenedor de encabezado) después de detener - fragmentmanager no inyectar su fragmento en el contenedor – merovingen

1

Por si alguien tiene curiosidad por qué su primer intento falló:

  • ciclo de vida eventos se publican en el hilo de interfaz de usuario
  • Fragment.onCreateView es un evento de ciclo de vida
  • Activity.onCreate es un ciclo de vida evento
  • .getView() devuelve la vista creada en Fragment.onCreateView
  • commit publicar un evento de ciclo de vida

Conclusión: el resultado de commit es visible desde el siguiente bucle, que es después de onCreate devueltos.

Uno podría intentar forzar commit para ser inmediato con getSupportFragmentManager().executePendingTransactions(), después de leer la documentación en él.

Cuestiones relacionadas