6

I have a ListView with several rows. Each row has a button.

I want the button to start a FragmentTransaction to replace the Fragment that the ListView is in.

However, in the getView() method of the Adapter, this line does not work:

FragmentTransaction t = getContext().getSupportFragmentManager().beginTransaction();

It does not like the context.

Can this be done in this way or does the Transaction have to happen elsewhere?

TheLettuceMaster
  • 15,594
  • 48
  • 153
  • 259

3 Answers3

34

First get the context in your Constructor and then try following code,

FragmentTransaction ft = ((FragmentActivity)context).getSupportFragmentManager().beginTransaction();
Melbourne Lopes
  • 4,817
  • 2
  • 34
  • 36
  • can we cast Activity (parent extends Activity but not FragmentActivity)? – Milon Nov 25 '16 at 07:11
  • No, Because Activity doesn't have Fragment Manager. So to use getSupportFragmentManager() method you need to cast instance of FragmentActivity only. – Melbourne Lopes Nov 28 '16 at 08:56
  • Thank you I was passing the FragmentManager as parameter and using that from adapter but it was showing parameter mismatch this one worked :) – Manoranjan Dec 22 '17 at 10:50
12

getSupportFragmentManager() is only defined for the class FragmentActivity, not for Context. Thus, the compiler can't resolve the call if you try to call it on an object of type Context.

You can use reflection to do this in a safe way. This will always work as long as you pass your FragmentActivity as the Context. Note: FragmentActivity is a subclass of Context, and thus you can pass FragmentActivity wherever you can pass Context.

So use this code instead:

if (getContext() instanceof FragmentActivity) {
    // We can get the fragment manager
    FragmentActivity activity = (FragmentActivity(getContext()));
    FragmentTransaction t = activity.getSupportFragmentManager().beginTransaction();
}
Tushar
  • 8,019
  • 31
  • 38
  • What if it is not an instance of fragmentActivity, and it is just an activity... how do you go about this – Lion789 Mar 02 '14 at 00:43
  • @Lion789 Well a non-fragment Activity wouldn't have a FragmentManager, and thus no `getSupportFragmentManager`or `getFragmentManager`, so you can't use Fragments with it. – Tushar Dec 14 '14 at 04:50
  • how can i use `getSupportFragmentManager() .beginTransaction() .replace(R.id.content_frame, Fragment_home.newInstance(), Fragment_home.TAG).commit();` in side array adapter.it getting error when i use it according to your solution – hash Jan 02 '15 at 11:53
5

I'd suggest you to pass FragmentManager instance to the Adapter constructor like that:

public class YourAdapter extends...

    private FragmentManage mFragmentManager;        

    public YourAdapter(FragmentManager fm) {
        mFragmentManager = fm;
    }

And use it explicitly:

FragmentTransaction ft = mFragmentManager.beginTransaction();

That should give you posibility to initialize Adapter with either Fragment.getFragmentManager() or FragmentActivity.getSupportFragmentManager() instance, since they are pointed at the same object

Mykhailo Gaidai
  • 3,130
  • 1
  • 21
  • 23
  • Doing `public YourAdapter(FragmentManager fm) {` cause an error that says `Implicit Super constructor ArrayAdapter() is undefined. Must implicitly invoke another constructor`? – TheLettuceMaster Mar 11 '13 at 00:43
  • So, you are overriding `ArrayAdapter`? You should call `super()` constructor with corresponding params. If you provide the source code of your adapter's constructor I can provide exact line – Mykhailo Gaidai Mar 11 '13 at 00:46