Usando o contexto em um fragmento


664

Como posso obter o contexto em um fragmento?

Preciso usar meu banco de dados cujo construtor aceita o contexto, mas, getApplicationContext()e FragmentClass.thisnão funciona, o que posso fazer?

Construtor de banco de dados

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

Respostas:


1313

Você pode usar getActivity(), que retorna a atividade associada a um fragment.
A atividade é uma context (já que Activityse estende Context) .


212
getActivity () pode retornar nulo se for chamado antes de onAttach do respectivo fragmento.
precisa saber é o seguinte

4
Eu estava lendo este blog do Google sobre vazamentos de memória ... android-developers.blogspot.com/2009/01/… . Se eu usar o método getActivity (), o aplicativo não correria o risco de vazamento de memória? O blog sugere "Tente usar o aplicativo de contexto em vez de uma atividade de contexto", o que não é realmente possível, pois getApplicationContext () funciona apenas para a classe Activity e não para a classe Fragment.
Simon

40
Uma solução para o problema de fragmentos desanexados é armazenar o valor de getActivity().getApplicationContext()em uma variável de instância quando o fragmento é criado e, em seguida, usar esse contexto sempre que desejar dentro da classe de fragmento. Esse contexto sobreviverá a desapegos de fragmentos.
Piovezan

8
Em vez de passar pelo contexto do aplicativo, crie um contexto estático dentro da classe Application e inicialize-o em OnCreate (): MyApplication.sContext = getApplicationContext (); então você pode acessá-lo de qualquer atividade / fragmento sem se preocupar com desapego.
Eduko 23/02

3
@ milaniez: getActivitysempre esteve disponível. É getContexto que foi adicionado em API 23.
mhsmith

130

Para fazer como a resposta acima, você pode substituir o onAttachmétodo do fragmento:

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}

3
Eu recomendaria isso, pois getActivity () retorna nulo se onAttach ainda não foi chamado.
precisa saber é o seguinte

9
Mas, lembre-se, quando onAttach () é chamado, não há visualizações. Portanto, você ainda não pode fazer nada com visualizações!
Zordid

2
@iambox e se DatabaseHelpernecessário um em FragmentActivityvez de um Activity? Por exemplo, para um Adapter...
Jago 19/06

4
Se você armazenar uma referência a sua atividade em onAttach(Activity activity)seguida, você deve liberá-lo emonDetach()
vovahost

3
O onAttachmétodo foi preterido,Overrides deprecated method in 'android.support.v4.app.Fragment'
Muhammad Saqib

24

Sempre use o método getActivity () para obter o contexto de sua atividade anexada, mas lembre-se sempre de uma coisa: os fragmentos são um pouco instáveis ​​e getActivityretornam nulos algumas vezes; portanto, sempre verifique o método isAdded () do fragmento antes de obter o contexto getActivity().


15
Eu não diria que os fragmentos são "um pouco instáveis", parece normal que getActivity () retorne nulo quando o fragmento não pertence a uma atividade. Supõe-se que getActivity () "não retorne nulo" (o que está errado), o que tornaria seu aplicativo (e não a classe Fragment) instável.
que você

3
@ personne3000 Eu gostaria de ouvir mais. Quando um fragmento não pertence a uma atividade? Quando isso está acontecendo e por quê? Devemos verificar isAdded () no fragmento para usar getActivity ()? Alguma regra de ouro?
Sotti 22/04

2
@ Sotti Convido você a criar uma nova pergunta para isso (ou procurar uma já existente), pois esse assunto específico é um pouco diferente da pergunta original. Você pode dar uma olhada em developer.android.com/guide/components/fragments.html#Lifecycle para obter informações gerais. Basicamente, antes de onAttach e depois de onDetach, nenhuma atividade. E entre onAttach e onActivityCreated, o onCreate da atividade ainda não foi chamado. Ao usar getActivity (), verifique se sua atividade já foi criada e pense no que aconteceria se ela fosse destruída ou se seu fragmento fosse desanexado.
que você

22

A maneira mais fácil e precisa de obter o contexto do fragmento que encontrei é obtê-lo diretamente a partir do ViewGroupmomento em que você chamar o onCreateViewmétodo, pelo menos aqui, você tem certeza de que não será nulo por getActivity():

public class Animal extends Fragment { 
  Context thiscontext;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    thiscontext = container.getContext();

10
esse é o contexto do contêiner, acho ... não "esse contexto".
Fattie

2
@ AG1, você poderia explicar por que o seu código falhou? Esta é até agora a melhor solução que eu tenho.
Machado

3
Na verdade, em dialogFragments, o contêiner pode ser nulo. Cuidado!
Lucas Teske

Essa solução deve ser usada no onViewCreated, não no onCreateView.
Andrea De Simone

13

Anteriormente eu estou usando onAttach (Activity activity)para chegar contextemFragment

Problema

O onAttach (Activity activity)método foi descontinuado no nível 23 da API.

Solução

Agora, para obter contexto Fragment, podemos usaronAttach (Context context)

onAttach (Context context)

  • Chamado quando um fragmento é anexado pela primeira vez a ele context. onCreate(Bundle)será chamado depois disso.

Documentação

/**
 * 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);
    }
}

CÓDIGO DE AMOSTRA

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

}

NOTA

Também podemos usar getActivity()para entrar context, Fragments mas getActivity()podemos retornar nullse o seu fragmentnão estiver atualmente anexado a um pai activity,


11
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    context=activity;
}

6

Você também pode obter o contexto do inflaterparâmetro, ao substituir onCreateView.

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

5

Outra abordagem alternativa é:

Você pode obter o contexto usando:

getActivity().getApplicationContext();

5

para obter o contexto dentro do fragmento será possível usando getActivity():

public Database()
{
    this.context = getActivity();
    DBHelper = new DatabaseHelper(this.context);
}
  • Cuidado, para usar o Activityassociado ao fragmento getActivity(), você pode usá-lo, mas não é recomendável, pois isso causará vazamentos de memória.

Eu acho que uma abordagem melhor deve estar recebendo Activityo onAttach()método:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = activity;
}

Você não deve usar getActivity em um fragmento para obter uma visualização, a menos que essa visualização faça parte da atividade. Por que você inflaria uma visão em um fragmento e nem sequer faria referência a alguma coisa?
tyczj

Esta resposta é sobre algo diferente, você está falando sobre qual visualização hiearchy procurar por visualizações. Activity.findViewByIdÉ apenas um método de conveniência para procurar uma visualização na visualização de conteúdo registrado dessa atividade (definido setContentView). No exemplo correto, você está chamando View.findViewByIde não Activity.findViewByIdestá chamando o método na visualização raiz correta . Problema totalmente diferente e, obviamente, você não poderá encontrar sua visão em uma pesquisa que não a sustenta.
JHH

3

getContext() veio na API 23. Substitua-o por getActivity () em todo o código.

Veja se ele corrige o erro. Tente usar métodos que estejam entre o nível mínimo e mínimo da API, caso contrário, esse erro ocorrerá.


3

Desde nível API 23 não é getContext(), mas se você quer apoiar as versões mais antigas que você pode usar getActivity().getApplicationContext()enquanto eu ainda recomendo usar a versão apoio do Fragmentque é android.support.v4.app.Fragment.


2

getActivity() é um filho do contexto, de modo que deve funcionar para você


2

Use fragmentos da Biblioteca de suporte -

android.support.v4.app.Fragment

e depois substituir

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

Dessa forma, você pode ter certeza de que o contexto sempre será um valor não nulo.


2

Você tem opções diferentes:

  • Se seu minSDK <= 21, você pode usar getActivity(), pois esse é um Context.
  • Se o seu minSDK for> = 23, você poderá usá-lo getContext().

Se você não precisa oferecer suporte a versões antigas, continue com getContext().


2

Para o Kotlin, você pode usar contextdiretamente em fragmentos. Mas, em alguns casos, você encontrará um erro como

Incompatibilidade de tipos: o tipo inferido é Contexto? mas o contexto era esperado

para isso você pode fazer isso

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))

Obrigado por disponibilizar uma versão do Kotlin, que funciona bem, no entanto, estou tentando obter o Contexto para o Picasso.get (), com ele e ele nunca funciona, tentei tudo o que posso das amostras acima para obter o contexto. Na melhor das hipóteses, recebo esta mensagem - Muitos argumentos foram passados ​​... Por favor, ajude. val ctx = context?: return Picasso.get (ctx) .load (selectedGallery.imageUrl) .placeholder (R.mipmap.ic_launcher) .into (galleryImage)
Ade

@Ade No seu fragmento, tente usar "atividade !!" em vez de "ctx" e deixe-me saber isso ajuda ou não
Kishan Solanki

@ KishanSolanki124. Muito obrigado pela resposta rápida. Tentei sua sugestão, com o mesmo resultado - Ainda não está funcionando. O prompt exato do erro é - Muitos argumentos para diversão pública aberta get (): Picasso !. Esta mensagem me faz pensar, talvez algo mais seja o erro? Felizmente, encontrei uma maneira de seguir em frente com meu trabalho usando Picasso sem ter contexto. Obrigado novamente.
Ade


2

Com a API 29+ no Kotlin, eu tive que fazer

activity?.applicationContext!!

Um exemplo seria

ContextCompat.getColor(activity?.applicationContext!!, R.color.colorAccent),

Contexto! = ApplicationContext
Gabriele Mariotti

1

Idealmente, você não precisa usar globals. O fragmento possui notificações diferentes, sendo uma delas onActivityCreated. Você pode obter a instância da atividade neste evento de ciclo de vida do fragmento.

Então: você pode desreferenciar o fragmento para obter a atividade, o contexto ou o contexto da aplicação como desejar:

this.getActivity()fornecerá o identificador para a atividade this.getContext(), fornecerá o identificador para o contexto this.getActivity().getApplicationContext(), fornecerá o identificador para o contexto do aplicativo. De preferência, você deve usar o contexto do aplicativo ao transmiti-lo para o banco de dados.


1

A maneira mais simples é usar getActivity(). Mas acho que a maior confusão de usar ogetActivity() método para obter o contexto aqui é uma exceção de ponteiro nulo.

Para isso, verifique primeiro com o isAdded()método que determinará se ele foi adicionado ou não e, em seguida, podemos usar o getActivity()para obter o contexto de Activity.


1
Como isso é diferente da resposta de Ankur Chaudhary ?
Peter Mortensen

1

Você pode ligar getActivity()ou,

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

1

Você pode usar o método getActivity () para obter contexto ou Você pode usar o método getContext ().

 View root = inflater.inflate(R.layout.fragment_slideshow, container, false);
    Context c = root.getContext();

Espero que ajude!


1
Existem outras respostas que fornecem a pergunta do OP e foram publicadas há algum tempo. Ao postar uma resposta, consulte: Como redigir uma boa resposta? , adicione uma nova solução ou uma explicação substancialmente melhor, especialmente ao responder a perguntas mais antigas.
help-info.de

0

O método getContext () ajuda a usar o contexto da classe em uma atividade de fragmento.


0

Eu acho que você pode usar

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

      Context context = 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

Também você pode usar:

inflater.getContext();

mas eu preferiria usar

getActivity()

ou

getContext

0

Eu preciso de contexto para usar o fragmento arrayAdapter IN, quando eu estava usando o erro getActivity, mas quando eu o substituo por getContext, ele funciona para mim

listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));

0

Você pode usar getActivity()ougetContext no fragmento.

Documentação

/**
 * 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();
}

e

 /**
     * Return the {@link Context} this fragment is currently associated with.
     *
     * @see #requireContext()
     */
    @Nullable
    public Context getContext() {
        return mHost == null ? null : mHost.getContext();
    }

Dica profissional

Verifique sempre, if(getActivity!=null)pois pode ser nulo quando o fragmento não está anexado à atividade. Às vezes, fazer uma operação longa no fragmento (como buscar dados da API restante) leva algum tempo. e se o usuário navegar para outro fragmento. Então, getActivity será nulo. E você receberá o NPE se não o tiver tratado.


Esta é uma documentação do método getActivity (), apenas para mostrar que eles podem ser nulos. Aqui mHost é instância de FragmentHostCallbackclasse.
Khemraj

0

Em seu fragmento

((Name_of_your_Activity) getActivity()).helper

Em atividade

DbHelper helper = new DbHelper(this);

0

Fragmento interno para amostra kotlin ajudaria alguém

textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

se você usar a ligação de dados;

bindingView.textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

Onde bindingView é inicializado em onCreateView como este

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

bindingView = DataBindingUtil.inflate(inflater, R.layout.your_layout_xml, container, false)

0

O método requireContext () é a opção mais simples

requireContext()

Exemplo

MyDatabase(requireContext())
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.