¿Por qué quiero evitar constructores no predeterminados en fragmentos?

Estoy creando una aplicación con Fragments y en una de ellas, creé un constructor no predeterminado y obtuve esta advertencia:

 Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead 

¿Puede alguien decirme por qué esta no es una buena idea?

¿Puedes sugerir también cómo lograría esto?

 public static class MenuFragment extends ListFragment { public ListView listView1; Categories category; //this is my "non-default" constructor public MenuFragment(Categories category){ this.category = category; }.... 

Sin usar el constructor no predeterminado?

Cree un objeto agrupado e inserte sus datos (en este ejemplo su objeto Category ). Tenga cuidado, no puede pasar este objeto directamente al paquete, a menos que sea serializable. Creo que es mejor construir tu objeto en el fragmento y poner solo un identificador o algo más en el paquete. Este es el código para crear y adjuntar un paquete:

 Bundle args = new Bundle(); args.putLong("key", value); yourFragment.setArguments(args); 

Después de eso, en tu fragmento, accede a los datos:

 Type value = getArguments().getType("key"); 

Eso es todo.

Parece que ninguna de las respuestas responde realmente “por qué usar paquete para pasar parámetros en lugar de constructores no predeterminados”

La razón por la que debe pasar parámetros a través del paquete es porque cuando el sistema restaura un fragment (por ejemplo, en el cambio de configuración), restaurará automáticamente su bundle .

Las devoluciones de llamada como onCreate o onCreateView deben leer los parámetros del bundle ; de esta forma, se garantiza que restablecerá el estado del fragment correctamente en el mismo estado con el fragment se inicializó el fragment (tenga en cuenta que este estado puede ser diferente del onSaveInstanceState bundle que se pasa) a onCreate/onCreateView )

La recomendación de usar el newInstance() estático newInstance() es solo una recomendación. Puedes usar un constructor no predeterminado pero asegúrate de rellenar los parámetros de inicialización en el bundle dentro del cuerpo de ese constructor. Y lea esos parámetros en los onCreate() o onCreateView() .

Tu Fragment no debería tener constructores por la forma en que FragmentManager crea. Debería tener un método estático newInstance() definido con los parámetros que necesita, luego agruparlos y establecerlos como los argumentos del fragmento, que luego puede acceder con el parámetro Bundle .

Por ejemplo:

 public static MyFragment newInstance(int title, String message) { MyFragment fragment = new MyFragment(); Bundle bundle = new Bundle(2); bundle.putInt(EXTRA_TITLE, title); bundle.putString(EXTRA_MESSAGE, message); fragment.setArguments(bundle); return fragment ; } 

Y lea estos argumentos en onCreate :

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); title = getArguments().getInt(EXTRA_TITLE); message = getArguments().getString(EXTRA_MESSAGE); //... } 

De esta manera, si se desconecta y se vuelve a conectar, el estado del objeto se puede almacenar a través de los argumentos, al igual que los bundles adjuntos a Intent s.

Si usa el parámetro para alguna clase. prueba esto

 SomeClass mSomeInstance; public static final MyFragment newInstance(SomeClass someInstance){ MyFragment f = new MyFragment(); f.mSomeInstance = someInstance; return f; } 

Creo que no hay diferencia entre el constructor estático y dos constructores (vacío y parametrizado que almacena argumentos en el paquete de argumentos de Fragment), lo más probable es que esta regla empírica se cree para reducir la probabilidad de olvidar la implementación de un constructor no-arg en Java , que no se genera implícitamente cuando hay sobrecarga.

En mis proyectos utilizo Kotlin e implemento fragmentos con un constructor no-arg primario y un constructor secundario para los argumentos que simplemente los almacena en un paquete y lo establece como argumentos de Fragmento, todo funciona bien.

¡Utilicé el método y está funcionando!

 public FragmentHome() { // Required empty public constructor } public void FragmentHomeConstructor(Context context, String stringBundle) { mContext = context; mStringBundle = stringBundle; } 

¡Haz esto en el método oncreate () de fragment para obtener el contexto sin ningún error!

 mContext = this.getActivity(); 

En el método oncreate() de tu actividad:

 FragmentHome fragmentHome = new FragmentHome(); fragmentHome.FragmentHomeConstructor(mContext, mStringBundle);