Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I get Fragment not attached to a context. What context need to use?

I get the Exception from Firebase Crashlytics

Fatal Exception: java.lang.IllegalStateException: Fragment MyFragment{122418b (05b123e6-aa8d-4de4-8f7e-49c95018234b)} not attached to a context.
       at androidx.fragment.app.Fragment.requireContext(Fragment.java:774)
       at androidx.fragment.app.Fragment.getResources(Fragment.java:838)
       at com.timskiy.pregnancy.fragments.MyFragment$1$1.run(MyFragment.java:156)
       at android.os.Handler.handleCallback(Handler.java:907)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:216)
       at android.app.ActivityThread.main(ActivityThread.java:7625)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

Error line from fragment

imageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.blue));

also tried

imageView.setColorFilter(getResources().getColor(R.color.blue));

I use viewPager in Activity and FragmentStatePagerAdapter. What context I need to use in fragment to setColorFilter? Thx

like image 550
TimWeb Avatar asked Oct 31 '19 13:10

TimWeb


People also ask

How do you pass a fragment as a context?

Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml. In the above code, we have taken two fragments.

How do I pass context from activity to fragment?

Instead of passing around the application context, create a static context inside your Application class and initialize it onCreate(): MyApplication. sContext = getApplicationContext(); then you can access it from any activity/fragment without worrying about detachment. @milaniez: getActivity has always been available.

Does fragment has its own context?

To get the context in a fragmented use getActivity(), which renders the activity associated with a fragment. The activity is a context (since Activity continues Context).


3 Answers

Add this in your fragment:

private Context mContext;    

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

@Override
public void onDetach() {
    super.onDetach();
    mContext = null;
}

And in your image view

imageView.setColorFilter(ContextCompat.getColor(mContext, R.color.blue));
like image 190
Zeeshan Avatar answered Nov 16 '22 02:11

Zeeshan


Try to use application context to fetch app resources to prevent IllegalStateException (not attached to a context)

// Init global variable with the application context first:
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    if (appContext == null)
        appContext = context.getApplicationContext();
}

Then use appContext var anywhere you want to get app resources ex:

imageView.setColorFilter(ContextCompat.getColor(appContext, R.color.blue));
like image 44
Royi Avatar answered Nov 16 '22 01:11

Royi


You are getting this crash because you are trying to call getContext() from a fragment that has already been detached from the parent Activity.

From the stacktrace it appears that there is a call to MyFragment.java line 156 from a Handler, this leads me to assume that its some background work happening but its getting completed when the fragment has been detached.

A quick fix for this would be to check if the fragment is attached to activity before attempting to execute any line of code that modifies the view.

if (isAttachedToActivity()){
  imageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.blue));
}

or

if (isAttachedToActivity()){
  imageView.setColorFilter(getResources().getColor(R.color.blue));
}

The isAttachedToActivity() looks like this:

public boolean isAttachedToActivity() {
    boolean attached = isVisible() && getActivity() != null;
    return attached;
}
like image 30
kev Avatar answered Nov 16 '22 00:11

kev