フラグメントでのコンテキストの使用


664

フラグメントのコンテキストを取得するにはどうすればよいですか?

コンストラクターがコンテキストで使用するデータベースを使用する必要がgetApplicationContext()ありFragmentClass.thisますが、機能しません。どうすればよいですか?

データベースコンストラクタ

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

回答:


1313

getActivity()関連付けられているアクティビティを返すを使用できますfragment
アクティビティはcontext Activity拡張以降Contextです。


212
getActivity()は、それぞれのフラグメントのonAttachの前に呼び出された場合、nullを返すことができます。
arne.jans

4
私はメモリリークについてこのGoogleブログを読んでいました... android-developers.blogspot.com/2009/01/…。getActivity()メソッドを使用すると、アプリでメモリリークのリスクがなくなりますか?ブログは「コンテキストアクティビティの代わりにコンテキストアプリケーションを使用してみてください」と提案しています。これは、getApplicationContext()がアクティビティクラスでのみ機能し、フラグメントクラスでは機能しないため、実際には不可能です。
Simon 14

40
デタッチされたフラグメントの問題の解決策は、getActivity().getApplicationContext()フラグメントの作成時にインスタンス変数にの値を格納し、フラグメントクラス内で必要なときにいつでもそのコンテキストを使用することです。そのコンテキストは、フラグメントの切り離しを切り抜けます。
Piovezan 14年

8
アプリケーションコンテキストを渡す代わりに、アプリケーションクラス内に静的コンテキストを作成し、onCreate()で初期化します。MyApplication.sContext = getApplicationContext(); その後、分離を心配することなく、任意のアクティビティ/フラグメントからアクセスできます。
Eduko、2015

3
@milaniez:getActivityいつでも利用できます。それはだgetContextAPI 23に追加された
mhsmith

130

上記の答えとして、onAttachフラグメントのメソッドをオーバーライドできます:

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

3
onAttachがまだ呼び出されていない場合、getActivity()はnullを返すため、これをお勧めします。
arne.jans

9
ただし、onAttach()が呼び出されたときにビューがないことに注意してください。したがって、ビューではまだ何もできません!
Zordid 2013年

2
@iambox DatabaseHelper必要な場合、FragmentActivity代わりにActivity?たとえば、Adapter...
Jago

4
アクティビティへの参照を保存するonAttach(Activity activity)場合は、リリースする必要がありますonDetach()
vovahost

3
このonAttach方法は廃止されましたOverrides deprecated method in 'android.support.v4.app.Fragment'
Muhammad Saqib

24

常にgetActivity()メソッドを使用して、アタッチされたアクティビティのコンテキストを取得しますが、常に1つのことを覚えておいてください。フラグメントは少し不安定で、getActivitynull を返すことがあるので、そのため、によってコンテキストを取得する前に、フラグメントのisAdded()メソッドを常に確認してくださいgetActivity()


15
フラグメントが「少し不安定」であるとは言いませんが、フラグメントがアクティビティに属していない場合、getActivity()がnullを返すのはごく普通のようです。これは、getActivity()が「nullを返すべきではない」(これは間違っている)ことを前提としています。これにより、(Fragmentクラスではなく)アプリが不安定になります。
personne3000

3
@ personne3000もっと聞きたいです。フラグメントがアクティビティに属していないのはいつですか?これはいつ起こり、なぜですか?getActivity()を使用するには、フラグメントのisAdded()をチェックする必要がありますか?経験則はありますか?
ソッティ2015

2
@ソッティこの特定の主題は元の質問とは少し異なるので、私はあなたがこのために新しい質問を作成する(または既存の質問を探す)ことをお勧めします。一般的な情報については、developer.android.com / guide / components / fragments.html#Lifecycleをご覧ください。基本的に、onAttachの前とonDetachの後で、アクティビティはありません。また、onAttachとonActivityCreatedの間では、アクティビティのonCreateはまだ呼び出されていません。getActivity()を使用する場合は、アクティビティがすでに作成されていることを確認し、それが破棄された場合やフラグメントがデタッチされた場合にどうなるかを考えてください。
personne3000

22

私が見つけたフラグメントのコンテキストを取得する最も簡単で最も正確な方法は、少なくともここでメソッドViewGroupを呼び出すときにそれから直接取得することonCreateViewですgetActivity()

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

10
それがコンテナのコンテキストです。「このコンテキスト」ではないのではないでしょうか。
Fattie、2014年

2
@ AG1なぜコードがクラッシュしたのか説明してください。これは、これまでのところ私が得た最高のソリューションです
Machado

3
実際には、dialogFragmentsでは、コンテナ nullにすることができます。気をつけて!
Lucas Teske 2015

このソリューションは、onCreateViewではなく、onViewCreatedで使用する必要があります。
Andrea De Simone

13

以前、私はonAttach (Activity activity)入るのcontextに使っていましたFragment

問題

このonAttach (Activity activity)メソッドはAPIレベル23で廃止されました。

解決

ここでコンテキストを取得 Fragmentするために使用できますonAttach (Context context)

onAttach (Context context)

  • フラグメントが最初ににアタッチされたときに呼び出されますcontextonCreate(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()取得するcontextFragments はなくgetActivity()戻ることができnull、あなたがあれば fragment、現在の親に接続されていませんactivity


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

6

inflaterオーバーライドするときに、パラメータからコンテキストを取得することもできますonCreateView

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

5

別の代替アプローチは次のとおりです。

以下を使用してコンテキストを取得できます。

getActivity().getApplicationContext();

5

Fragment内のコンテキストを取得するには、以下を使用しgetActivity()ます。

public Database()
{
    this.context = getActivity();
    DBHelper = new DatabaseHelper(this.context);
}
  • 注意して、をActivity使用してフラグメントに関連付けられるようにするにはgetActivity()、それを使用できますが、メモリリークが発生するため、お勧めしません。

より良いアプローチActivityonAttach()メソッドから取得する必要があると思います:

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

とにかくそのビューがアクティビティの一部でない限り、フラグメントでgetActivityを使用してビューを取得しないでください。フラグメントのビューを膨らませて、そこから何も参照しないのはなぜですか?
tyczj 14

この答えは何か別のものです。あなたはビューを検索するためのどのビュー階層を話しているのですか?はActivity.findViewById、そのアクティビティの登録済みコンテンツビュー(で設定setContentView)でビューを検索するための便利な方法にすぎません。正しい例ではView.findViewById、ではなくActivity.findViewByIdを呼び出しており、正しいルートビューでメソッドを呼び出しています。まったく異なる問題であり、そのビューを保持していないビュー階層ではビューを見つけることができません。
JHH 2016年

3

getContext() API 23で導入されました。コードのすべての場所でgetActivity()に置き換えてください。

エラーが修正されるかどうかを確認します。ターゲットとminimun APIレベルの間にあるメソッドを使用してみてください。そうしないと、このエラーが発生します。


3

APIレベル23ので、そこにされてgetContext()、あなたが使用することができます古いバージョンをサポートしたい場合はgetActivity().getApplicationContext()、私はまだのサポートバージョン使用することをお勧めしている間Fragmentであるがandroid.support.v4.app.Fragment



2

サポートライブラリのフラグメントを使用-

android.support.v4.app.Fragment

そしてオーバーライドする

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

これにより、コンテキストが常にnull以外の値になることを確認できます。


2

さまざまなオプションがあります。

  • あなたのminSDK <= 21場合は、使用することができgetActivity()、これがあることから、Context
  • minSDKが23以上の場合は、を使用できますgetContext()

古いバージョンをサポートする必要がない場合は、を使用してくださいgetContext()


2

Kotlinの場合context、フラグメントで直接使用できます。しかし、いくつかのケースでは、次のようなエラーが見つかります

タイプの不一致:推論されたタイプはコンテキストですか?コンテキストが期待されていました

そのためにこれを行うことができます

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

正常に機能するKotlinバージョンを利用していただきありがとうございます。ただし、Picasso.get()のコンテキストを取得しようとしていますが、機能せず、上記のサンプルから可能な限りすべてを試し、コンテキストを取得しました。せいぜいこのメッセージが表示されます-渡された引数が多すぎます...助けてください。val ctx = context?:return Picasso.get(ctx).load(selectedGallery.imageUrl).placeholder(R.mipmap.ic_launcher).into(galleryImage)
Ade

@Adeあなたのフラグメントでは、「アクティビティ!!」を使用してみてください 代わりに「CTX」の、私はそれができますか知っている
のKishan Solanki

@ KishanSolanki124。迅速な対応ありがとうございました。私は同じ結果であなたの提案を試しました-まだ動作していません。正確なエラープロンプトは-public open fun get()の引数が多すぎます:Picasso!。このメッセージは私に考えさせます、おそらく何か他のエラーですか?嬉しいことに、コンテキストを取得せずにピカソを使用して私の仕事を進める方法を見つけました。再度、感謝します。
Ade


2

KotlinのAPI 29+では、私はしなければなりませんでした

activity?.applicationContext!!

例は

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

Context!= ApplicationContext
Gabriele Mariotti

1

理想的には、グローバルを使用する必要はありません。フラグメントにはさまざまな通知があり、そのうちの1つはonActivityCreatedです。フラグメントのこのライフサイクルイベントでアクティビティのインスタンスを取得できます。

次に、フラグメントを逆参照して、必要に応じてアクティビティ、コンテキスト、またはアプリケーションコンテキストを取得できます。

this.getActivity()アクティビティへの this.getContext()ハンドルを提供し、コンテキスト this.getActivity().getApplicationContext()へのハンドルを提供し、アプリケーションコンテキストへのハンドルを提供します。データベースに渡す場合は、アプリケーションコンテキストを使用することをお勧めします。


1

簡単な方法はを使用することgetActivity()です。しかしgetActivity()、ここでコンテキストを取得するためにメソッドを使用する際の大きな混乱は、nullポインタ例外だと思います。

そのためには、まず、isAdded()それが追加されているかどうかを判断するメソッドを確認し、次にを使用しgetActivity()てActivityのコンテキストを取得します。


1
これはAnkur Chaudharyの回答とどう違うのですか?
Peter Mortensen

1

あなたは呼び出すことができgetActivity()、または

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

1

getActivity()メソッドを使用してコンテキストを取得するか、getContext()メソッドを使用できます。

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

お役に立てば幸いです。


1
OPの質問を提供する他の回答があり、それらはしばらく前に投稿されました。回答投稿するときは、「良い回答を書くにはどうすればよいですか」を参照してください。、特に古い質問に答える場合は、新しいソリューションまたは大幅に優れた説明を追加してください。
help-info.de

0

getContext()メソッドは、フラグメントアクティビティでクラスのコンテキストを使用するのに役立ちます。


0

使えると思います

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

また、あなたは使うことができます:

inflater.getContext();

でも使いたい

getActivity()

または

getContext

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フラグメントで使用できます。

ドキュメンテーション

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

プロのヒント

フラグメントがアクティビティに関連付けられていない場合はnullなる可能性があるif(getActivity!=null)ため常に確認してください。フラグメントで長い操作を実行する場合(rest APIからデータをフェッチする場合など)は、時間がかかる場合があります。ユーザーが別のフラグメントに移動した場合。その後、getActivityはnullになります。そして、それを処理しなかった場合は、NPEを取得します。


これはgetActivity()メソッドの説明であり、nullの可能性があることを示しています。ここで、mHostはFragmentHostCallbackクラスのインスタンスです。
ケムラジ

0

あなたの断片

((Name_of_your_Activity) getActivity()).helper

活動中

DbHelper helper = new DbHelper(this);

0

kotlinサンプルの内部フラグメントは誰かを助けるでしょう

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

データバインディングを使用する場合。

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

bindingViewがで初期化されている場合onCreateViewこのよう

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.