5

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>
user2573690
  • 5,493
  • 9
  • 43
  • 61

9 Answers9

21

you can try this

FragmentTransaction ft = ((AppCompatActivity) mContext).getSupportFragmentManager()
                        .beginTransaction();
Jenis Kasundra
  • 583
  • 9
  • 19
6

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)
DINA TAKLIT
  • 7,074
  • 10
  • 69
  • 74
4

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();
Ness Tyagi
  • 2,008
  • 24
  • 18
1

in adapter use

appCompatActivity object instead of context

it will work

Akash kv
  • 429
  • 4
  • 13
0

pass context in adapter and use

context.getSupportFragmentManager().beginTransaction();
Akash kv
  • 429
  • 4
  • 13
0

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;
        }
Akash kv
  • 429
  • 4
  • 13
  • How does that code open the fragment? If I do this.appCompatActivity I still can't get the fragment manager. Doing this ((FragmentActivity)mContext).getSupportFragmentManager().beginTransaction() works to get around the cannot resolve error, but I still dont see the fragment opening. – user2573690 Aug 05 '16 at 03:24
0

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);
       }
    });
Viktor Yakunin
  • 2,927
  • 3
  • 24
  • 39
  • Thanks for the help! I am creating the adapter in an AsyncTask that is part of my main activity, I tried to adapt your code to move what is in the onCreate to the onPostExecute section of my AsyncTask but this does not work, it cannot resolve the OnDetailsRequestListener method which I created in my activity. Any ideas? – user2573690 Aug 07 '16 at 15:54
0

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");
Harish Reddy
  • 922
  • 10
  • 20
-2
FragmentTransaction trans =((FragmentActivity)context).getSupportFragmentManager()
                        .beginTransaction();

If you try this, you will see it work.

Dan Lowe
  • 51,713
  • 20
  • 123
  • 112