Wie kann ich den Kontext in einem Fragment erhalten?
Ich muss meine Datenbank verwenden, deren Konstruktor den Kontext berücksichtigt, aber getApplicationContext()
und FragmentClass.this
funktionieren nicht. Was kann ich tun?
Datenbankkonstruktor
public Database(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
Sie können getActivity()
verwenden, das die mit fragment
verknüpfte Aktivität zurückgibt.
Die Aktivität ist eine context
(da Activity
Context
erweitert) .
Um wie oben zu antworten, können Sie die Fragmentmethode onAttach
überschreiben:
public static class DummySectionFragment extends Fragment{
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
DBHelper = new DatabaseHelper(activity);
}
}
Verwenden Sie immer die Methode getActivity () , um den Kontext Ihrer angehängten Aktivität abzurufen. Beachten Sie jedoch Folgendes: Fragmente sind leicht instabil und getActivity
gibt einige Male null zurück die isAdded () Methode des Fragments, bevor der Kontext von getActivity()
abgerufen wird.
Der einfachste und präziseste Weg, den Kontext des gefundenen Fragments zu ermitteln, besteht darin, ihn direkt aus der ViewGroup
-Methode abzurufen, wenn Sie onCreateView
aufrufen. Zumindest werden Sie hier nicht null für getActivity()
erhalten:
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;
}
Bisher habe ich onAttach (Activity activity)
verwendet, um context
in Fragment
zu erhalten.
Problem
Die Methode onAttach (Activity activity)
wurde in API-Ebene 23 verworfen.
Lösung
Um den Kontext in Fragment
zu erhalten, können wir onAttach (Context context)
verwenden
onAttach (Context context)
context
angehängt wird. Danach wird onCreate(Bundle)
aufgerufen.Dokumentation
/**
* 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);
}
}
MUSTERCODE
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;
}
}
Wir können auch getActivity()
verwenden, um context
in Fragments
zu erhalten, aber getActivity()
kann null
zurückgeben, wenn Ihr fragment
ist zurzeit keinem übergeordneten activity
zugeordnet.
um den Kontext innerhalb des Fragments zu erhalten, können Sie getActivity()
verwenden:
public Database()
{
this.context = getActivity();
DBHelper = new DatabaseHelper(this.context);
}
getActivity()
das Activity
erhalten, das dem Fragment zugeordnet ist. Sie können es verwenden, es wird jedoch nicht empfohlen, da es zu Speicherverlusten führt.Ich denke, ein besserer Ansatz muss darin bestehen, die Activity
von der onAttach()
-Methode zu erhalten:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
}
Ein anderer alternativer Ansatz ist:
Sie können den Kontext abrufen mit:
getActivity().getApplicationContext();
Sie können den Kontext auch über den Parameter inflater
abrufen, wenn Sie onCreateView
überschreiben.
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* ... */
Context context = inflater.getContext();
/* ... */
}
}
Seit API-Level 23 gibt es getContext()
, aber wenn Sie ältere Versionen unterstützen möchten, können Sie getActivity().getApplicationContext()
verwenden, während ich weiterhin die Unterstützungsversion von Fragment
empfehle, die Android.support.v4.app.Fragment
ist.
getContext()
ist in API 23 enthalten. Ersetzen Sie es überall im Code durch getActivity ().
Überprüfen Sie, ob der Fehler behoben ist. Versuchen Sie, Methoden zu verwenden, die zwischen der Ziel- und der minimun-API-Ebene liegen. Andernfalls tritt dieser Fehler auf.
Verwenden Sie Fragmente aus Support Library -
Android.support.v4.app.Fragment
und dann überschreiben
void onAttach (Context context) {
this.context = context;
}
Auf diese Weise können Sie sicher sein, dass der Kontext immer ein Wert ungleich Null ist.
Sie haben verschiedene Möglichkeiten:
getActivity()
verwenden, da dies ein Context
ist.getContext()
verwenden.Wenn Sie keine alten Versionen unterstützen müssen, gehen Sie zu getContext()
.
getActivity()
ist ein untergeordnetes Element von Context, sodass es für Sie funktionieren sollte
Für Kotlin können Sie context
direkt in Fragmenten verwenden. Aber in einigen Fällen werden Sie einen Fehler wie finden
Typenkonflikt: Abgeleiteter Typ ist Kontext? aber Kontext wurde erwartet
dafür kannst du das machen
val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, Android.R.color.black))
Sie können getActivity()
aufrufen oder,
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
}
In kotlin benutze einfach activity
anstelle von getActivity()
Idealerweise sollten Sie keine globalen Zeichen verwenden müssen. Das Fragment weist verschiedene Benachrichtigungen auf, von denen sich eine aufActivityCreated befindet. Sie können die Instanz der Aktivität in diesem Lebenszyklusereignis des Fragments abrufen.
Dann: Sie können das Fragment dereferenzieren, um Aktivität, Kontext oder Anwendungskontext nach Ihren Wünschen abzurufen:
this.getActivity()
gibt Ihnen das Handle für die Aktivität. this.getContext()
gibt Ihnen das Handle für den Kontext. this.getActivity().getApplicationContext()
gibt Ihnen das Handle für den Anwendungskontext. Verwenden Sie vorzugsweise den Anwendungskontext, wenn Sie ihn an die Datenbank weiterleiten.
Der einfache Weg ist, getActivity()
zu verwenden. Aber ich denke, die größte Verwirrung bei der Verwendung der getActivity()
-Methode, um den Kontext hier abzurufen, ist eine Nullzeiger-Ausnahme.
Überprüfen Sie dazu zunächst mit der Methode isAdded()
, ob sie hinzugefügt wurde oder nicht, und verwenden Sie dann die Methode getActivity()
, um den Kontext der Aktivität abzurufen.
Auf dir Fragment
((Name_of_your_Activity) getActivity()).helper
Bei Aktivität
DbHelper helper = new DbHelper(this);
Ich brauche Kontext für die Verwendung von ArrayAdapter IN Fragment, wenn ich getActivity Fehler verwendete, aber wenn ich es durch getContext ersetze, funktioniert es für mich
listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),Android.R.layout.simple_list_item_1 ,listSensorType));
Ich denke, Sie können verwenden
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Context context = getActivity.getContext();
}
}
Die Methode getContext () hilft dabei, den Kontext der Klasse in einer Fragmentaktivität zu verwenden.
getActivity()
oder getContext
verwenden.Dokumentation
/**
* 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();
}
und
/**
* Return the {@link Context} this fragment is currently associated with.
*
* @see #requireContext()
*/
@Nullable
public Context getContext() {
return mHost == null ? null : mHost.getContext();
}
Überprüfen Sie immer if(getActivity!=null)
, da kann null sein, wenn das Fragment nicht an die Aktivität angehängt ist. Manchmal dauert es einige Zeit, eine lange Operation in Fragmenten durchzuführen (wie das Abrufen von Daten von der Rest-API). und wenn der Benutzer zu einem anderen Fragment navigiert. Dann ist getActivity null. Und Sie werden NPE bekommen, wenn Sie nicht damit umgehen.
Auch können Sie verwenden:
inflater.getContext();
aber ich würde es vorziehen, zu verwenden
getActivity()
oder
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;
}
}