Utilisation du contexte dans un fragment
Comment puis-je obtenir le contexte dans un fragment?
J'ai besoin d'utiliser ma base de données dont le constructeur prend dans le contexte, mais getApplicationContext()
et FragmentClass.this
n'est pas ce que je peux faire?
Constructeur de base de données
public Database(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
23 réponses
Vous pouvez utiliser getActivity()
, qui retourne l'activité associée à un fragment.
L'activité est un contexte (puisque l'Activité s'étend au Contexte).
Pour faire comme la réponse ci-dessus, vous pouvez remplacer les onAttach
méthode de fragment:
public static class DummySectionFragment extends Fragment{
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
DBHelper = new DatabaseHelper(activity);
}
}
Utilisez toujours la méthodegetActivity () pour obtenir le contexte de votre activité attachée, mais rappelez-vous toujours une chose: les Fragments sont légèrement instables et getActivity
renvoie null certaines fois, donc pour cela, vérifiez toujours la méthode isAdded() de fragment avant d'obtenir le contexte par getActivity()
.
Le moyen le plus simple et le plus précis d'obtenir le contexte du fragment que j'ai trouvé est de l'obtenir directement à partir de la ViewGroup
lorsque vous appelez la méthode onCreateView
au moins ici vous êtes sûr de ne pas obtenir null pour getActivity()
:
public class Animal extends Fragment {
Context thiscontext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
thiscontext = container.getContext();
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
context=activity;
}
Pour obtenir le contexte à l'intérieur du Fragment sera possible à l'aide de getActivity()
:
public Database()
{
this.context = getActivity();
DBHelper = new DatabaseHelper(this.context);
}
- attention, pour obtenir le
Activity
associé au fragment en utilisantgetActivity()
, Vous pouvez l'utiliser mais n'est pas recommandé cela provoquera des fuites de mémoire.
Je pense qu'un meilleur aproach doit obtenir le Activity
de la méthode onAttach()
:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
}
Une Autre approche alternative est:
Vous pouvez obtenir le contexte en utilisant:
getActivity().getApplicationContext();
Vous pouvez également obtenir le contexte à partir du paramètre inflater
, en remplaçant onCreateView
.
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* ... */
Context context = inflater.getContext();
/* ... */
}
}
getContext()
entré dans API 23. Remplacez-le par getActivity() partout dans le code.
Voir si elle corrige l'erreur. Essayez d'utiliser des méthodes qui se trouvent entre le niveau de L'API target et minimun, sinon cette erreur se produira.
Depuis le niveau de L'API 23, Il y a getContext()
mais si vous voulez prendre en charge les anciennes versions, vous pouvez utiliser getActivity().getApplicationContext()
alors que je recommande toujours d'utiliser la version de support de Fragment
qui est android.support.v4.app.Fragment
.
getActivity()
est un enfant de Contexte qui devrait fonctionner pour vous
Vous avez différentes options:
- Si votre minSDK getActivity(), puisque c'est un
Context
. - Si votre minSDK est >=23, alors vous pouvez utiliser
getContext()
.
Si vous n'avez pas besoin de prendre en charge les anciennes versions, utilisez getContext()
.
Pour Kotlin vous pouvez utiliser context
directement dans les fragments. Mais dans certains cas, vous trouverez une erreur comme
Incompatibilité de Type: le type inféré est le contexte? mais le contexte était attendu
Pour cela, vous pouvez faire ceci
val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
Idéalement, vous ne devriez pas avoir besoin d'utiliser des globals. Le fragment a différentes notifications, l'une d'entre elles étant onActivityCreated. Vous pouvez obtenir l'instance de l'activité dans cet événement de cycle de vie du fragment.
Ensuite: vous pouvez déréférencer le fragment pour obtenir activity, context ou applicationcontext comme vous le souhaitez:
this.getActivity()
vous donnera la poignée à l'activité
this.getContext()
vous donnera une poignée au contexte
this.getActivity().getApplicationContext()
vous donnera le handle du contexte de l'application. Vous devriez utilisez de préférence le contexte de l'application lorsque vous le transmettez à la base de données.
Le moyen simple est d'utiliser getActivity()
. Mais je pense que la confusion majeure de l'utilisation de la méthode getActivity()
pour obtenir le contexte ici est une exception de pointeur null.
Pour cela, vérifiez d'abord avec la méthode isAdded()
qui déterminera si elle est ajoutée ou non, puis nous pouvons utiliser le getActivity()
pour obtenir le contexte de L'activité.
Utiliser des fragments de Bibliothèque de prise en charge -
android.support.v4.app.Fragment
, puis remplacer
void onAttach (Context context) {
this.context = context;
}
De cette façon, vous pouvez être sûr que le contexte sera toujours une valeur non nulle.
La méthode GetContext() permet d'utiliser le contexte de la classe dans une activité de fragment.
Vous pouvez appeler getActivity()
ou
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
}
Je pense que vous pouvez utiliser
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Context context = getActivity.getContext();
}
}
public class MenuFragment extends Fragment implements View.OnClickListener {
private Context mContext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentMenuBinding binding=FragmentMenuBinding.inflate(inflater,container,false);
View view=binding.getRoot();
mContext=view.getContext();
return view;
}
}
Vous pouvez également utiliser:
inflater.getContext();
Mais je préférerais utiliser
getActivity()
Ou
getContext
J'ai besoin de contexte pour utiliser arrayAdapter dans fragment, quand j'utilisais getActivity une erreur se produit mais quand je le remplace par getContext cela fonctionne pour moi
listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));
, Vous pouvez utiliser getActivity()
ou getContext
dans le Fragment.
Documentation
/**
* Return the {@link FragmentActivity} this fragment is currently associated with.
* May return {@code null} if the fragment is associated with a {@link Context}
* instead.
*
* @see #requireActivity()
*/
@Nullable
final public FragmentActivity getActivity() {
return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}
Et
/**
* Return the {@link Context} this fragment is currently associated with.
*
* @see #requireContext()
*/
@Nullable
public Context getContext() {
return mHost == null ? null : mHost.getContext();
}
Astuce Pro
Vérifiez toujours if(getActivity!=null)
parce que , il peut être null lorsque le fragment n'est pas attaché à l'activité. Parfois, faire une opération longue dans un fragment (comme extraire des données de l'api rest) prend un certain temps. et si l'utilisateur navigue vers un autre fragment. Alors getActivity sera null. Et vous obtiendrez NPE si vous ne l'avez pas géré.