Использование контекста во фрагменте

567

Как я могу получить контекст в фрагменте?

Мне нужно использовать мою базу данных, конструктор которой принимает контекст, но getApplicationContext() и FragmentClass.this не работают, так что я могу сделать?

Конструктор базы данных

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}
Теги:
android-fragments
android-context

25 ответов

1205
Лучший ответ

Вы можете использовать getActivity(), которая возвращает активность, связанную с fragment.
Активность является context (поскольку Activity расширяет Context).

  • 198
    getActivity () может вернуть значение null, если оно вызывается перед onAttach соответствующего фрагмента.
  • 0
    да, так что проверяйте, имеет ли оно значение null, прежде чем использовать что-либо с контекстом
Показать ещё 6 комментариев
124

Чтобы сделать как ответ выше, вы можете переопределить метод фрагмента onAttach:

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}
  • 3
    Я бы порекомендовал это, так как getActivity () возвращает ноль, если onAttach еще не вызван.
  • 7
    Но имейте в виду, что при вызове onAttach () представления отсутствуют. Так что вы ничего не можете сделать с представлениями еще!
Показать ещё 5 комментариев
22

Всегда используйте метод getActivity(), чтобы получить контекст вашей приложенной активности, но всегда помните одну вещь: фрагменты немного нестабильны и getActivity возвращает null some раз, поэтому для этого всегда проверяйте isAdded() метод фрагмента, прежде чем получить контекст getActivity().

  • 12
    Я бы не сказал, что фрагменты «немного нестабильны», вполне нормально, что getActivity () возвращает ноль, когда фрагмент не принадлежит действию. Предполагается, что getActivity () «не должна возвращать ноль» (что неверно), что сделает ваше приложение (а не класс Fragment) нестабильным.
  • 2
    @ personne3000 Я хотел бы услышать больше. Когда фрагмент не принадлежит Деятельности? Когда это происходит и почему? Должны ли мы проверять isAdded () во фрагменте, чтобы использовать getActivity ()? Любое эмпирическое правило?
Показать ещё 1 комментарий
16

Самый простой и точный способ получить контекст найденного фрагмента - получить его непосредственно из ViewGroup, когда вы вызываете метод onCreateView, по крайней мере, здесь вы уверены, что не получите null для getActivity()

public class Animal extends Fragment { 
  Context thiscontext;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    thiscontext = container.getContext();
  • 10
    это контекст контейнера, я думаю ... а не "этот контекст".
  • 0
    Этот код сделал мой код сбой ... избежать.
Показать ещё 2 комментария
9
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    context=activity;
}
5

чтобы получить контекст внутри Фрагмента, можно будет использовать 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;
}
  • 0
    Вы не должны использовать getActivity во фрагменте, чтобы получить представление, если только это представление не является частью действия. Зачем вам раздувать вид фрагмента, а потом даже не ссылаться на него?
  • 0
    Этот ответ о чем-то другом, вы говорите о том, какое представление hiearchy для поиска представлений в. Activity.findViewById - это просто удобный метод для поиска представления в зарегистрированном представлении содержимого этого действия (устанавливается через setContentView ). В вашем правильном примере вы вызываете View.findViewById , а не Activity.findViewById , и вы вызываете метод в правильном корневом представлении. Совершенно другая проблема, и, очевидно, вы не сможете найти свое представление в иерархии представлений, которая не поддерживает это представление.
Показать ещё 1 комментарий
4

Другой альтернативный подход:

Вы можете получить контекст, используя:

getActivity().getApplicationContext();
  • 0
    @tyczj читать полностью, чтобы понять по вашей ссылке
3

Начиная с уровня API 23 существует getContext(), но если вы хотите поддерживать более старые версии, вы можете использовать getActivity().getApplicationContext(), пока я по-прежнему рекомендую использовать версию поддержки Fragment, которая является android.support.v4.app.Fragment.

3

Вы также можете получить контекст из параметра inflater при переопределении onCreateView.

public static class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
        /* ... */
        Context context = inflater.getContext();
        /* ... */
    }
}
3

getContext() появился в API 23. Замените его getActivity() всюду в коде.

Проверьте, исправлена ​​ли ошибка. Попытайтесь использовать методы, находящиеся между уровнями target и minimun API, иначе эта ошибка появится.

2

Раньше я использовал 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,

2

Для Kotlin вы можете использовать context непосредственно в фрагментах. Но в некоторых случаях вы найдете ошибку, например

Тип несоответствия: предполагаемый тип - это контекст? но ожидался контекст

для этого вы можете это сделать

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
  • 0
    Спасибо за использование Kotlin-версии, которая работает нормально, однако я пытаюсь получить Context для Picasso.get (), но он так и не работает, я попробовал все, что мог, из примеров выше, чтобы получить контекст. В лучшем случае я получаю это сообщение -Слишком много аргументов передано ... Пожалуйста, помогите. val ctx = context?: вернуть Picasso.get (ctx) .load (selectedGallery.imageUrl) .placeholder (R.mipmap.ic_launcher) .into (galleryImage)
  • 0
    @Ade В своем фрагменте попробуйте использовать "активность !!" вместо "ctx" и дайте мне знать, это помогает или нет
Показать ещё 1 комментарий
2

Использовать фрагменты из Библиотеки поддержки -

android.support.v4.app.Fragment

а затем переопределить

void onAttach (Context context) {
  this.context = context;
}

Таким образом, вы можете быть уверены, что в контексте всегда будет ненулевое значение.

2

У вас есть разные варианты:

  • Если ваш minSDK <= 21, вы можете использовать getActivity(), так как это Context.
  • Если ваш minSDK = > 23, вы можете использовать getContext().

Если вам не нужно поддерживать старые версии, перейдите к getContext().

2

getActivity() является дочерним элементом контекста, поэтому он должен работать для вас

1

Вы можете позвонить getActivity() или,

public void onAttach(Context context) {
    super.onAttach(context);
    this.activity = (CashActivity) context;
    this.money = this.activity.money;
}
1

В идеале вам не нужно использовать глобальные переменные. Фрагмент имеет разные уведомления, один из которых - onActivityCreated. Вы можете получить экземпляр активности в этом жизненном цикле фрагмента.

Затем: вы можете разыменовать фрагмент, чтобы получить активность, контекст или applicationcontext по вашему желанию:

this.getActivity() предоставит вам ручку активности this.getContext() даст вам описание контекста this.getActivity().getApplicationContext() предоставит вам дескриптор контекста приложения. Вы должны предпочтительно использовать контекст приложения при передаче его на db.

1

Простым способом является использование getActivity(). Но я думаю, что основная путаница использования метода getActivity() для получения контекста здесь - это исключение из null-указателя.

Для этого сначала проверьте метод isAdded(), который определит, добавлен он или нет, и затем мы можем использовать getActivity(), чтобы получить контекст Activity.

0

На тебе фрагмент

((Name_of_your_Activity) getActivity()).helper

По активности

DbHelper helper = new DbHelper(this);
0

Мне нужен контекст для использования фрагмента 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));
0

Вы можете использовать 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();
    }

Pro tip

Проверяйте всегда, if(getActivity!=null) поскольку он может быть нулевым, если фрагмент не привязан к активности. Иногда длительная работа в фрагменте (например, выборка данных из rest api) занимает некоторое время. и если пользователь перейдет к другому фрагменту. Тогда getActivity будет null. И вы получите NPE, если не справитесь с этим.

  • 0
    что такое mHost ???
  • 0
    Это документация по методу getActivity (), просто для того, чтобы показать, что он может быть нулевым. Здесь mHost является экземпляром класса FragmentHostCallback .
0

Также вы можете использовать:

inflater.getContext();

но я бы предпочел использовать

getActivity()

или же

getContext
0
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;
    }
}
0

Я думаю, вы можете использовать

public static class MyFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

      Context context = getActivity.getContext();

  }
}
0

Метод getContext() помогает использовать Контекст класса в активности фрагмента.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню