Как я могу получить контекст в фрагменте?
Мне нужно использовать мою базу данных, конструктор которой принимает контекст, но getApplicationContext()
и FragmentClass.this
не работают, так что я могу сделать?
Конструктор базы данных
public Database(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
Вы можете использовать getActivity()
, которая возвращает активность, связанную с fragment
.
Активность является context
(поскольку Activity
расширяет Context
).
Чтобы сделать как ответ выше, вы можете переопределить метод фрагмента onAttach
:
public static class DummySectionFragment extends Fragment{
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
DBHelper = new DatabaseHelper(activity);
}
}
Всегда используйте метод getActivity(), чтобы получить контекст вашей приложенной активности, но всегда помните одну вещь: фрагменты немного нестабильны и getActivity
возвращает null some раз, поэтому для этого всегда проверяйте isAdded() метод фрагмента, прежде чем получить контекст getActivity()
.
Самый простой и точный способ получить контекст найденного фрагмента - получить его непосредственно из ViewGroup
, когда вы вызываете метод onCreateView
, по крайней мере, здесь вы уверены, что не получите null для 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;
}
чтобы получить контекст внутри Фрагмента, можно будет использовать getActivity()
:
public Database()
{
this.context = getActivity();
DBHelper = new DatabaseHelper(this.context);
}
Activity
, связанный с фрагментом, используя getActivity()
, вы можете его использовать, но не рекомендуется, чтобы он вызывал утечку памяти.Я думаю, что лучший aproach должен получить Activity
от метода onAttach()
:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
}
Activity.findViewById
- это просто удобный метод для поиска представления в зарегистрированном представлении содержимого этого действия (устанавливается через setContentView
). В вашем правильном примере вы вызываете View.findViewById
, а не Activity.findViewById
, и вы вызываете метод в правильном корневом представлении. Совершенно другая проблема, и, очевидно, вы не сможете найти свое представление в иерархии представлений, которая не поддерживает это представление.
Другой альтернативный подход:
Вы можете получить контекст, используя:
getActivity().getApplicationContext();
Начиная с уровня API 23 существует getContext()
, но если вы хотите поддерживать более старые версии, вы можете использовать getActivity().getApplicationContext()
, пока я по-прежнему рекомендую использовать версию поддержки Fragment
, которая является android.support.v4.app.Fragment
.
Вы также можете получить контекст из параметра inflater
при переопределении onCreateView
.
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* ... */
Context context = inflater.getContext();
/* ... */
}
}
getContext()
появился в API 23. Замените его getActivity() всюду в коде.
Проверьте, исправлена ли ошибка. Попытайтесь использовать методы, находящиеся между уровнями target и minimun API, иначе эта ошибка появится.
Раньше я использовал onAttach (Activity activity)
чтобы получить context
в Fragment
проблема
Метод onAttach (Activity activity)
устарел на уровне API 23.
Решение
Теперь, чтобы получить контекст во Fragment
мы можем использовать onAttach (Context context)
onAttach (Context context)
context
. onCreate(Bundle)
будет вызываться после этого.Документация
/**
* 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);
}
}
ОБРАЗЕЦ КОДА
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;
}
}
Мы также можем использовать getActivity()
для получения context
во Fragments
но getActivity()
может возвращать значение null
если ваш fragment
не привязан к родительскому activity
,
Для Kotlin вы можете использовать context
непосредственно в фрагментах. Но в некоторых случаях вы найдете ошибку, например
Тип несоответствия: предполагаемый тип - это контекст? но ожидался контекст
для этого вы можете это сделать
val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
Использовать фрагменты из Библиотеки поддержки -
android.support.v4.app.Fragment
а затем переопределить
void onAttach (Context context) {
this.context = context;
}
Таким образом, вы можете быть уверены, что в контексте всегда будет ненулевое значение.
У вас есть разные варианты:
getActivity()
, так как это Context
.getContext()
.Если вам не нужно поддерживать старые версии, перейдите к getContext()
.
getActivity()
является дочерним элементом контекста, поэтому он должен работать для вас
Вы можете позвонить getActivity()
или,
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
}
В идеале вам не нужно использовать глобальные переменные. Фрагмент имеет разные уведомления, один из которых - onActivityCreated. Вы можете получить экземпляр активности в этом жизненном цикле фрагмента.
Затем: вы можете разыменовать фрагмент, чтобы получить активность, контекст или applicationcontext по вашему желанию:
this.getActivity()
предоставит вам ручку активности
this.getContext()
даст вам описание контекста
this.getActivity().getApplicationContext()
предоставит вам дескриптор контекста приложения. Вы должны предпочтительно использовать контекст приложения при передаче его на db.
Простым способом является использование getActivity()
. Но я думаю, что основная путаница использования метода getActivity()
для получения контекста здесь - это исключение из null-указателя.
Для этого сначала проверьте метод isAdded()
, который определит, добавлен он или нет, и затем мы можем использовать getActivity()
, чтобы получить контекст Activity.
На тебе фрагмент
((Name_of_your_Activity) getActivity()).helper
По активности
DbHelper helper = new DbHelper(this);
Мне нужен контекст для использования фрагмента arrayAdapter IN, когда я использовал ошибку getActivity, но когда я заменяю его getContext, он работает для меня
listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));
getActivity()
или getContext
в Fragment.Документация
/**
* 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();
}
а также
/**
* Return the {@link Context} this fragment is currently associated with.
*
* @see #requireContext()
*/
@Nullable
public Context getContext() {
return mHost == null ? null : mHost.getContext();
}
Проверяйте всегда, if(getActivity!=null)
поскольку он может быть нулевым, если фрагмент не привязан к активности. Иногда длительная работа в фрагменте (например, выборка данных из rest api) занимает некоторое время. и если пользователь перейдет к другому фрагменту. Тогда getActivity будет null. И вы получите NPE, если не справитесь с этим.
FragmentHostCallback
.
Также вы можете использовать:
inflater.getContext();
но я бы предпочел использовать
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;
}
}
Я думаю, вы можете использовать
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Context context = getActivity.getContext();
}
}
Метод getContext() помогает использовать Контекст класса в активности фрагмента.