android - sirve - onAttach(Activity) obsoleto: donde puedo verificar si la actividad implementa la interfaz de devoluciĆ³n de llamada
onstart android fragment (7)
Uso el Fragment
nativo en lugar del de la Biblioteca de soporte . Puse ambos métodos en onAttach()
en mi código e hice algunas depuraciones en dispositivos con diferentes versiones de SDK. Encontre eso:
SDK 22 y onAttach(Activity)
siguientes : solo se onAttach(Activity)
. No es sorprendente, en realidad, porque onAttach(Context)
solo se introdujo en el SDK 23.
SDK 23 y superior : onAttach(Context)
se llama primero y luego onAttach(Activity)
. (Esto es coherente con lo que dijo @ Zsolt Mester sobre el código fuente en otra respuesta a esta publicación).
Como minSdkVersion
para mi aplicación estaba por debajo de 23, decidí omitir onAttach(Context)
completo y simplemente agregar la @SuppressWarnings("deprecation")
a mi onAttach(Activity)
existente onAttach(Activity)
.
Antes de API 23 utilicé los métodos Fragment''s onAttach para obtener mi instancia listener, luego la referencia se limpia dentro de Detach. ex:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = null;
try {
mListener = (SellFragmentListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SellFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
¿Es seguro hacer el mismo control dentro de Attach (contexto contextual) o hay una mejor manera de obtener la instancia de actividad del titular?
Bueno, lo que está en desuso es onAttach(Activity activity);
método, pero todo el flujo permanece. así que no puedes hacer nada realmente como onAttach(Activity activity);
va a seguir siendo compatible el tiempo suficiente.
Verifica el código fuente:
/**
* Called when a fragment is first attached to its context.
* {@link #onCreate(Bundle)} will be called after this.
*/
public void onAttach(Context context) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onAttach(hostActivity);
}
}
/**
* @deprecated Use {@link #onAttach(Context)} instead.
*/
@Deprecated
public void onAttach(Activity activity) {
mCalled = true;
}
Entonces onAttach(Activity activity)
llama al onAttach(Context context)
si hay una actividad de host. Puede usar el onAttach(Activity activity)
forma segura.
He enfrentado la misma situación. He revisado varias publicaciones y finalmente implementé mi código en el bloque de fragmentos onCreate (). Hasta ahora no me he enfrentado a ningún problema y creo que no sería un problema ya que onCreate se llama inmediatamente después de la conexión en el ciclo de vida.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
listnener = (TilesOnClickListnener)getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(getActivity().toString() + " must implement OnArticleSelectedListener");
}
}
public class MainActivity extends AppCompatActivity implements topsection.TopSectionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void createMeme(String top, String bottom){
bottomsection fragmentbottom = (bottomsection) getSupportFragmentManager().findFragmentById(R.id.fragment2);
fragmentbottom.setMemeText(top, bottom);
}
}
Como se muestra en la respuesta de Zsolt Mester, onAttach(Activity activity)
está en desuso en favor de onAttach(Context context)
. Por lo tanto, todo lo que necesita hacer es verificar que el contexto sea una actividad.
En Android Studio, si vas a Archivo> Nuevo> Fragmento , puedes obtener el código generado automáticamente que contendrá la sintaxis adecuada.
import android.support.v4.app.Fragment;
...
public class MyFragment extends Fragment {
private OnFragmentInteractionListener mListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflate fragment layout
return inflater.inflate(R.layout.fragment_myfragment, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Notas
Dado que la Actividad principal debe implementar nuestro
OnFragmentInteractionListener
(la interfaz nombrada arbitrariamente), la comprobación(context instanceof OnFragmentInteractionListener)
garantiza que el contexto sea realmente la actividad.Tenga en cuenta que estamos utilizando la biblioteca de soporte. De
onAttach(Context context)
contrario, las versiones de API pre API 23 no utilizaríanonAttach(Context context)
.
Ver también
Nunca tuve que usar onAttach(Context context)
pero creo que tu código es básicamente bueno. Así que aquí está mi sugerencia, usando su código:
public void onAttach (Context context) {
super.onAttach(context);
try {
Activity activity = (Activity) context;
mListener = (SellFragmentListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SellFragmentListener");
}
}
La principal diferencia es que puedo escribir el context
para obtener la Actividad. Esto se debe a que el contexto se puede propagar a la subclase que es la actividad.
Otro problema, la API 23 todavía está lejos de ahora para que nos preocupemos. Si te preocupa, usar build pragma (build estática) puede ser una buena opción.