user2573690
user2573690

Reputation: 6013

getSupportFragmentManager() undefined in adapter when using AppCompatActivity

I have an activity (MainActivity) which extends AppCompatActivity because I am using some of the material design elements in my app.

I then have an array adapter with a few fields and a button. This adapter has a separate view and is injected into my MainActivity layout.

When I click the button on the adapter view, I want to open a new fragment which displays a bunch of text, however, I can't seem to do this and I think it is because I am not extending FragmentActivity in my MainActivity? I read on another post that I should be able to extend AppCompatActivity and still be able to reference the fragment manager...here is my code to open the fragment:

In my custom array adapter, onClick() of a button:

holder.desc.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
      JobDescFragment fragment= new JobDescFragment();
      FragmentTransaction transaction =      getSupportFragmentManager().beginTransaction();
      transaction.replace(R.id.fragment_container, fragment);
      transaction.addToBackStack(null);  
      transaction.commit();
  }
});

The error I get is that it cannot resolve getSupportFragmentManager(). What am I doing wrong?

I am importing android.support.v4.app.Fragment and .FragmentManager in my adapter.

Thanks in advance for the help!

EDIT:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <com.lorentzos.flingswipe.SwipeFlingAdapterView
        android:id="@+id/frame"
        android:background="@color/laborswipe_lightgray"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:context=".MainActivity"
        android:layout_gravity="top"   />

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</merge>

Upvotes: 5

Views: 15779

Answers (9)

DINA TAKLIT
DINA TAKLIT

Reputation: 8408

In kotlin it will be like this for example. I have tried it and it work perfectly

val dialog = IntervAddFragment()//The fragment that u want to open for example
       val ft = (context as AppCompatActivity).supportFragmentManager.beginTransaction()
        dialog.show(ft, ContentValues.TAG)

Upvotes: 6

Harish Reddy
Harish Reddy

Reputation: 992

From your class

  YourAdapter=new YourAdapter(context, list, YourClass.this.getSupportFragmentManager)

Adapter

  public Adapter(context, list, FragmentManager manager){ 
  this.manager=manager;

Action

 FragmentTransaction ft = fragmentcontext.beginTransaction();
            SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
            newFragment.setArguments(bundle);
            newFragment.show(ft, "slideshow");

Upvotes: 0

Sayeimehtap
Sayeimehtap

Reputation: 1

FragmentTransaction trans =((FragmentActivity)context).getSupportFragmentManager()
                        .beginTransaction();

If you try this, you will see it work.

Upvotes: -2

Ness Tyagi
Ness Tyagi

Reputation: 2028

Hi this is simple just pass the reference of YourParent Activity Just use the snippet like this below in Your Adapter class to open fragment

Fragment fragment = new YourFragment();
FragmentManager fm = ((MainActivity) mContext).getSupportFragmentManager();
                FragmentTransaction ft = fm.beginTransaction();
                ft.add(R.id.frame_container, fragment);
                ft.commit();

Upvotes: 4

Jenis Kasundra
Jenis Kasundra

Reputation: 583

you can try this

FragmentTransaction ft = ((AppCompatActivity) mContext).getSupportFragmentManager()
                        .beginTransaction();

Upvotes: 21

Viktor Yakunin
Viktor Yakunin

Reputation: 3296

To make the code more flexible and separate logic you should understand responsibilities of your components. It is clear that your Adapter should not know about the Fragment and what is base class of Activity. So what should you do?

In your Activity you should set a listener to item clicked event inside adapter:

public class YourActivity extends AppCompatActivity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_your);
          //... some findViewById, etc.
          YourAdapter adapter = new YourAdapter(this, data, new OnDetailsRequestListener(){
               public void onDetailsRequested(int itemId){
                    DetailsFragment fragment = DetailsFragment.newInstance(itemId);
                    getSupportFragmentManager().beginTransaction()
                         .replace(R.id.fragment_container, fragment)
                         .addToBackStack(null)
                         .commit();
               });
            //... recyclerView.setAdapter ... etc.

     }

 public interface onDetailsRequestListener{
      void onDetailsRequestLister(int itemId);//here could be whatever you want, itemId, details, whatever...
 }
}

And inside your adapter you would have:

//...
    public AdapterConstructor(Context context, ArrayList data, YourActivity.OnDetailsRequestListener detailsRequestListener) {
       this.data = data;
       this.context = context;
       this.detailsRequestListener = detailsRequestListener;
       //...
    }
    //Inside bindView
    holder.desc.setTag(position);
    holder.desc.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
          int position = (int)view.getTag();
          int itemId = data.get(position).getId();
          detailsRequestListener.onDetailsRequested(itemId);
       }
    });

Upvotes: 0

Akash kv
Akash kv

Reputation: 429

avoid unwanted codes

 public class AdapterRecyclerViewDoc extends RecyclerView.Adapter<AdapterRecyclerViewDoc.ShareDocViewHolder> {
        ArrayList<ModelDoc> arrayList;

        AppCompatActivity appCompatActivity;

        public AdapterRecyclerViewDoc(ArrayList<ModelDoc> arrayList, AppCompatActivity appCompatActivity) {
            this.arrayList=arrayList;
            this.appCompatActivity=appCompatActivity;
        }

        @Override
        public ShareDocViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            View v = LayoutInflater.from(parent.getContext()).inflate
                    (R.layout.recyclerview_item_doc, parent, false);
            ShareDocViewHolder eventViewHolder = new ShareDocViewHolder(v);
            this.appCompatActivity.getSupportFragmentManager();
             return eventViewHolder;
        }

Upvotes: 0

Akash kv
Akash kv

Reputation: 429

in adapter use

appCompatActivity object instead of context

it will work

Upvotes: 1

Akash kv
Akash kv

Reputation: 429

pass context in adapter and use

context.getSupportFragmentManager().beginTransaction();

Upvotes: 0

Related Questions