Comment puis-je obtenir le contexte dans un fragment?
Je dois utiliser ma base de données dont le constructeur prend en compte le contexte, mais getApplicationContext()
et FragmentClass.this
ne fonctionnent pas, que puis-je faire?
Constructeur de base de données
public Database(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
Vous pouvez utiliser getActivity()
, qui renvoie l'activité associée à un fragment
.
L'activité est une context
(puisque Activity
s'étend Context
) .
Pour faire comme la réponse ci-dessus, vous pouvez remplacer la méthode onAttach
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éthode getActivity () pour obtenir le contexte de votre activité attachée, mais souvenez-vous toujours d'une chose: les fragments sont légèrement instables et getActivity
renvoie des valeurs nulles à certains moments. la isAdded () méthode 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 méthode ViewGroup
lorsque vous appelez la méthode onCreateView
, au moins ici, vous êtes sûr de ne pas obtenir la valeur 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;
}
Auparavant, j'utilisais onAttach (Activity activity)
pour obtenir context
dans Fragment
Problème
La méthode onAttach (Activity activity)
est obsolète dans le niveau 23 de l'API.
Solution
Maintenant, pour obtenir le contexte dans Fragment
, nous pouvons utiliser onAttach (Context context)
onAttach (Context context)
context
. onCreate(Bundle)
sera appelé après cela.Documentation
/**
* Called when a fragment is first attached to its context.
* {@link #onCreate(Bundle)} will be called after this.
*/
@CallSuper
public void onAttach(Context context) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onAttach(hostActivity);
}
}
EXEMPLE DE CODE
public class FirstFragment extends Fragment {
private Context mContext;
public FirstFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rooView=inflater.inflate(R.layout.fragment_first, container, false);
Toast.makeText(mContext, "THIS IS SAMPLE TOAST", Toast.LENGTH_SHORT).show();
// Inflate the layout for this fragment
return rooView;
}
}
Nous pouvons également utiliser getActivity()
pour obtenir context
dans Fragments
mais getActivity()
peut renvoyer null
si le fragment
n'est pas actuellement associé à un parent activity
,
pour obtenir le contexte à l'intérieur du fragment sera possible en utilisant getActivity()
:
public Database()
{
this.context = getActivity();
DBHelper = new DatabaseHelper(this.context);
}
Activity
au fragment à l'aide de getActivity()
, vous pouvez l'utiliser, mais ce n'est pas recommandé, cela entraînerait des fuites de mémoire.Je pense qu'une meilleure approche doit être d'obtenir la 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
lors de la substitution de onCreateView
.
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* ... */
Context context = inflater.getContext();
/* ... */
}
}
Depuis le niveau 23 de l'API, il y a getContext()
, mais si vous souhaitez prendre en charge des versions plus anciennes, vous pouvez utiliser getActivity().getApplicationContext()
, mais je vous recommande néanmoins d'utiliser la version de support de Fragment
qui est Android.support.v4.app.Fragment
.
getContext()
est entré dans l'API 23. Remplacez-le par getActivity () partout dans le code.
Voir si cela corrige l'erreur. Essayez d'utiliser des méthodes situées entre le niveau cible et le niveau minimal de l'API, sinon cette erreur se produira.
Utiliser des fragments de Support Library -
Android.support.v4.app.Fragment
et ensuite 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.
Vous avez différentes options:
getActivity()
, car il s’agit d’un Context
.getContext()
.Si vous n'avez pas besoin de supporter les anciennes versions, utilisez getContext()
.
getActivity()
est un enfant de Context et devrait donc fonctionner pour vous.
Pour Kotlin, vous pouvez utiliser context
directement en fragments. Mais dans certains cas, vous trouverez une erreur comme
Incompatibilité de types: le type inféré est-il un contexte? mais le contexte était attendu
pour ça tu peux faire ça
val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, Android.R.color.black))
Vous pouvez appeler getActivity()
ou,
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
}
Dans kotlin utilisez simplement activity
au lieu de getActivity()
Idéalement, vous n’auriez pas besoin d’utiliser des globals. Le fragment a différentes notifications, l'une d'elles étant onActivityCreated. Vous pouvez obtenir l'instance de l'activité dans cet événement du cycle de vie du fragment.
Ensuite: vous pouvez déréférencer le fragment pour obtenir l’activité, le contexte ou le contexte d’application que vous le souhaitez:
this.getActivity()
vous donnera le descripteur de l'activité this.getContext()
vous fournira un descripteur du contexte this.getActivity().getApplicationContext()
vous fournira le descripteur du contexte de l'application. Vous devriez utiliser de préférence le contexte de l'application lorsque vous le transmettez à la base de données.
Le moyen le plus simple consiste à utiliser getActivity()
. Mais je pense que la confusion majeure d'utiliser la méthode getActivity()
pour obtenir le contexte ici est une exception de pointeur nul.
Pour cela, commencez par vérifier avec la méthode isAdded()
qui déterminera si elle est ajoutée ou non, puis nous pourrons utiliser la getActivity()
pour obtenir le contexte de Activity.
Sur ton fragment
((Name_of_your_Activity) getActivity()).helper
Sur l'activité
DbHelper helper = new DbHelper(this);
J'ai besoin de contexte pour utiliser arrayAdapter IN 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));
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();
}
}
getContext () méthode aide à utiliser le contexte de la classe dans une activité de fragment.
getActivity()
ou getContext
dans 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();
}
Vérifiez toujours if(getActivity!=null)
car il peut être nul lorsque le fragment n'est pas lié à l'activité. Parfois, effectuer de longues opérations fragmentées (comme récupérer des données depuis une api restante) prend un certain temps. et si l'utilisateur navigue vers un autre fragment. Ensuite, getActivity sera null. Et vous obtiendrez des NPE si vous ne les manipuliez pas.
Aussi, vous pouvez utiliser:
inflater.getContext();
mais je préférerais utiliser
getActivity()
ou
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;
}
}