32
  1. TabLayout

    • tab1 (Fragment1)
    • tab2 (Fragment2)
    • tab3 (Fragment3)
      • RecyclerView + CardView (OnClick)

On CardView ClickListner open another fragment in tab3. So how to open fragment in tab3.

Error is in getFragmentManager():

FragmentTransaction transaction = getFragmentManager().beginTransaction();

which gives

/Adapter/CardAdapter.java Error:cannot find symbol method getSupportFragmentManager()

Instead of this, I tried:

FragmentTransaction transaction = activity.getFragmentManager().beginTransaction();
FragmentTransaction transaction = itemview.getContext().getFragmentManager().beginTransaction();

But error is not resolve.

Here is my code:

 public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {

    List<NatureItem> mItems;
    private int lastPosition = -1;
    Context context;
    TaskFragment main;
    public CardAdapter(Context context,TaskFragment ma)
    {

        this.context=context;
        main=ma;
    }


    public CardAdapter() {
        super();
        mItems = new ArrayList<NatureItem>();
        NatureItem nature = new NatureItem();
        nature.setName("The Paris Attack 2015");
        nature.setDes("Lorem ipsum dolor sit amet.");
        nature.setThumbnail(R.drawable.news1);
        mItems.add(nature);

           }



    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.custom_list, viewGroup, false);
        ViewHolder viewHolder = new ViewHolder(v);

     return viewHolder;
    }

  
     @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        NatureItem nature = mItems.get(i);
        viewHolder.tvNature.setText(nature.getName());
        viewHolder.tvDesNature.setText(nature.getDes());
        viewHolder.imgThumbnail.setImageResource(nature.getThumbnail());
      //  setAnimation(viewHolder.card,i);
    }

   
    @Override
    public int getItemCount() {
        return mItems.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private int lastPosition = -1;
        public ImageView imgThumbnail;
        public TextView tvNature;
        public TextView tvDesNature;
       // Button btnclear,btncancle;
        CardView card;
        Activity activity;
        Context co;
        public ViewHolder(final View itemView) {
            super(itemView);
            imgThumbnail = (ImageView)     itemView.findViewById(R.id.img_thumbnail);
            tvNature = (TextView) itemView.findViewById(R.id.tv_nature);
            tvDesNature = (TextView) itemView.findViewById(R.id.tv_des_nature);
            card = (CardView) itemView.findViewById(R.id.card);



    card.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        
        Toast.makeText(itemView.getContext(), "Clicked Card...", Toast.LENGTH_LONG).show();
       
           ShareFragment newFragment = new ShareFragment();
            FragmentTransaction transaction =  getFragmentManager().beginTransaction();
            transaction.replace(R.id.viewFragments, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();

            }
    });
        
        }
    }
}
        
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Nikita Sukhadiya
  • 367
  • 2
  • 4
  • 10
  • What `fragment` version do you use? If you use the one from the `support library`, you need to get the `SupportFragmentManager`. Also, if you get an error in `logcat`, post it. – yennsarah Dec 16 '15 at 11:25
  • Instead of using context access your parent activity instance. Then it will allow to access fragmentmanager. Also you need to create interface to call fragment. – Piyush Dec 16 '15 at 12:36

6 Answers6

51

Open new fragment as follows in your onclick

@Override
public void onClick(View view){
    AppCompatActivity activity = (AppCompatActivity) view.getContext();
    Fragment myFragment = new MyFragment();
    activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, myFragment).addToBackStack(null).commit();
}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Parinda Rajapaksha
  • 2,963
  • 1
  • 36
  • 40
18

When you use adapter context then for access fragment manager you need to cast your context. So you should use this way.

YourParentActivity myActivity = (YourParentActivity)context

Now you can access method for fragment manager like ,

myActivity.getSupportFragmentManager();

But keep in your mind that your Fragment should be imported as a android.support.app.v4.Fragment otherwise there might be a casting problem.

If you open fragment for particular one tab then you should use getChildSupportFragmentManager() instead of getSupportFragmentManager()

Note : If you want to call fragment from adapter class then you should make interface and pass listener to your button click method and implement your activity with that interface.

Update :

Also you can pass FragmentManager to your adapter constructor. Like,

public FragmentManager f_manager;
public CardAdapter(Context context,TaskFragment ma , FragmentManager f_manager)
{
    this.context = context;
    this.f_manager = f_manager;
    main=ma;
}

And after that you can use this.f_manager in your adapter class getView() method.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Piyush
  • 18,895
  • 5
  • 32
  • 63
8

If you have used support library fragments or default fragments, be sure to use same of it every every where. And use "getSupportFragmentManager" or "getFragmentManager" carefully.

Pass context inside constructor.

public CardAdapter(Context context) {
        super();
        mItems = new ArrayList<NatureItem>();
        NatureItem nature = new NatureItem();
        nature.setName("The Paris Attack 2015");
        nature.setDes("Lorem ipsum dolor sit amet.");
        nature.setThumbnail(R.drawable.news1);
        mItems.add(nature);
               }

Inside onClick

....Your Code

ShareFragment newFragment = new ShareFragment();
FragmentTransaction transaction = /* Here is the change.*/context.getFragmentManager().beginTransaction();
    transaction.replace(R.id.viewFragments, newFragment);

...Your Code

Update

Inside onClick call mainActivity setFragment method to replace fragment.

((MainActivity) context).setFragment(yourFragment);


public void setFragment(Fragment frag){
FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.viewFragments, frag);
}
Tushar Sheth
  • 391
  • 4
  • 18
  • context not working...i add this **import android.support.v4.app.FragmentTransaction;** – Nikita Sukhadiya Dec 16 '15 at 12:09
  • `transaction.replace(R.id.viewFragments, frag);` _Wrong 2nd argument type_ **Error:(108, 20) error: no suitable method found for replace(int,android.support.v4.app.Fragment) method FragmentTransaction.replace(int,android.app.Fragment,String) is not applicable (actual and formal argument lists differ in length) method FragmentTransaction.replace(int,android.app.Fragment) is not applicable (actual argument android.support.v4.app.Fragment cannot be converted to android.app.Fragment by method invocation conversion)** – Nikita Sukhadiya Dec 16 '15 at 13:22
  • Recheck if you have used android.support.v4.app.Fragment.... And imported android.support.v4.app.FragmentTransaction... And use getSupportFragmentManager().beginTransaction().... – Tushar Sheth Dec 17 '15 at 05:13
  • Now this error is occurs... **Error : java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.MainActivity.setFragment(android.support.v4.app.Fragment)' on a null object reference** – Nikita Sukhadiya Dec 17 '15 at 05:46
  • You are close ! Check if "context" you are passing is not null.Then only use ((YourActivity) context).setFragment(yourFragment); – Tushar Sheth Dec 17 '15 at 05:54
4

For moving from one fragment to another(from RecyclerView MyViewHolder class) use this

Fragment fragment = new AttendanceFragment();
FragmentManager fragmentManager = ((FragmentActivity) mContext).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
General Grievance
  • 4,555
  • 31
  • 31
  • 45
3

For the ones using Kotlin, assuming the fragment class you want to start is called MyFragment, and the container where you will put this fragment has id fragment_container_view. Probably you will do this inside the bind method inside your view holder.

itemView.setOnClickListener {
    val activity  = it.context as? AppCompatActivity
    activity?.supportFragmentManager?.commit {
        addToBackStack(MyFragment::class.toString())
        setReorderingAllowed(true)
        replace<MyFragment>(R.id.fragment_container_view)
    }
}
lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
0

Try this sniped :

ShareFragment newFragment = new ShareFragment();
MainActivity mainActivity = (MainActivity)itemView.getContext()
mainActivity.getFragmentManager().beginTransaction()
.replace(R.id.viewFragments, newFragment)
.addToBackStack(null)
.commit();
Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148