1

My objective is to replace the Fragment inside viewpager. I got a matching solution for the same Replace one fragment with other

Below is the code i am using almost same from the above link

 public interface SecondPageFragmentListener {
     void onSwitchToNextFragment();
}

I have implemented the above interface in my ViewPager Adapter.I am just pasting my full Code for the Adapter so it easy to understand it for everyone

public class TabPagerAdapter extends FragmentPagerAdapter{

    private final Resources resources;
    private Context mContext;
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    Fragment result = null;
    FirstPageListener listener = new FirstPageListener();
    public TabPagerAdapter(final Resources resources, FragmentManager  fm,Context mContext) {
        super(fm);
        this.mContext = mContext;
        this.resources = resources;
    }


    public void updateData(){
        notifyDataSetChanged();
    }


    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                // First Fragment of First Tab
                result = new Position();
                break;
            case 1:
                // First Fragment of Second Tab
                result =  new Alerts();
                break;
            case 2:
                // First Fragment of Third Tab
                result = new Reports();
                break;
            default:
                result = null;
                break;
        }

        return result;
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(final int position) {
         switch (position) {
            case 0:
                return resources.getString(R.string.tab_position_title);
            case 1:
                return resources.getString(R.string.tab_alert_title);
            case 2:
                return resources.getString(R.string.tab_reports_title);
            default:
                return null;
            }
    }

    @Override
    public int getItemPosition(Object object)
    {
        if (object instanceof Alerts &&
                result instanceof CaptureIncident) {
            return POSITION_NONE;
        }
        if (object instanceof CaptureIncident &&
                result instanceof Alerts) {
            return POSITION_NONE;
        }
        return POSITION_UNCHANGED;
    }



    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment)   super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }



    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
    private final class FirstPageListener implements
        SecondPageFragmentListener {
        public void onSwitchToNextFragment() {

((AppCompatActivity)mContext).getSupportFragmentManager().beginTransaction().remove(result)
                .commit();
            if (result instanceof Alerts){
                result =   CaptureIncident.newInstance("","",listener);
            }else{ // Instance of NextFragment
                result =  Alerts.newInstance("","",listener);
            }
            notifyDataSetChanged();
         }
     }


 }

I have just created a Inner class and implemented my SecondPageFragmentListener interface as mentioned in the link.

Now I have init the interface in my Alert Fragment

static SecondPageFragmentListener secondPageListener;
    public static Alerts newInstance(String param1, String param2,SecondPageFragmentListener listener) {
        Alerts fragment = new Alerts();
        secondPageListener = listener;
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

Now I am calling the interface method on button click

secondPageListener.onSwitchToNextFragment();

Below is My Fragment Code

public class Alerts extends RootFragment{

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";


    private String mParam1;
    private String mParam2;
    private RecyclerView gridview;
    private GridAdapter gridAdapter;
    private GridLayoutManager gridLayoutManager;

    private OnFragmentInteractionListener mListener;
     public static SecondPageFragmentListener secondPageListener;
    public Alerts() {
        // Required empty public constructor
    }
    @SuppressLint("ValidFragment")
    public Alerts(SecondPageFragmentListener listener){
        secondPageListener = listener;
    }


    public static Alerts newInstance(String param1, String param2,SecondPageFragmentListener listener) {
        Alerts fragment = new Alerts();
        secondPageListener = listener;
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_alerts, container,  false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         initUiView();
         RecyclerListener();
}

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
         }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
        }
    }

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

     public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
     }

     private void initUiView() {
         gridview =  (RecyclerView)getActivity().findViewById(R.id.gridview);
         gridview.setHasFixedSize(true);
         gridview.setLayoutManager(new GridLayoutManager(getActivity(), 3));

        //list Population
         List<ItemObject> rowListItem = getAllItemList();
         gridAdapter = new GridAdapter(getActivity(),rowListItem);
         gridview.setAdapter(gridAdapter);
         gridAdapter.notifyDataSetChanged();
     }

      private List<ItemObject> getAllItemList(){

          List<ItemObject> allItems = new ArrayList<ItemObject>();
         allItems.add(new ItemObject("altercation","0,50 miles - 10 min ago", R.drawable.altercation));
         allItems.add(new ItemObject("offence","0,25 miles - 45 min ago", R.drawable.offence));
          allItems.add(new ItemObject("harassment","0,60 miles - 1h ago", R.drawable.harassment));
          allItems.add(new ItemObject("doubt","0,5 miles - 48 min ago", R.drawable.doubt));
          allItems.add(new ItemObject("incident","0,50 miles - 30 min ago", R.drawable.incident));

         return allItems;
     }

     private void RecyclerListener(){
    gridview.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), gridview, new ItemClickListener(){
             @Override
             public void onClick(View view, int position) {
                 Alerts.secondPageListener.onSwitchToNextFragment();
      }

             @Override
             public void onLongClick(View view, int position) {

             }
         }));
     }
}

But it showing me the error

  java.lang.NullPointerException
                                                                   at   
com.oxilo.mrsafer.fragement.Alerts$1.onClick(Alerts.java:173)

The error indicates that secondpagelitener is null.

Please help me to resolve the issue.

Also on the below link Replace one fragment with other

he implement the same interface in Fragment too as he already implemented the interface in view pager adapter. so why he is implementing in the Fragment too.From my understanding it wrong but please correct me if i am wrong.

Community
  • 1
  • 1
Nirmal
  • 939
  • 10
  • 24

2 Answers2

0

You are calling this code

public void onSwitchToNextFragment() {

    ((AppCompatActivity)mContext).getSupportFragmentManager().beginTransaction().remove(result).commit();
    if (result instanceof Alerts){
       result =   CaptureIncident.newInstance("","",listener);
    } else{ // Instance of NextFragment
       result =  Alerts.newInstance("","",listener);
    }
    notifyDataSetChanged();
}

From object created here:

case 1:
    // First Fragment of Second Tab
    result =  new Alerts();
    break;

so secondPageListener is not initialized yet. You can try to create change your code to this:

 @Override
 public Fragment getItem(int position) {

    switch (position) {
        case 0:
            // First Fragment of First Tab
            result = new Position();
            break;
        case 1:
            // First Fragment of Second Tab
            result =  Alerts.newInstance("","",listener); // This line is important
            break;
        case 2:
            // First Fragment of Third Tab
            result = new Reports();
            break;
        default:
            result = null;
            break;
    }

    return result;
}

EDIT

If it's going to be static then you can try this:

 @Override
 public Fragment getItem(int position) {

    switch (position) {
        case 0:
            // First Fragment of First Tab
            result = new Position();
            break;
        case 1:
            // First Fragment of Second Tab
            result =  Alerts.newInstance("","",listener); // This line is important
            Alerts.secondPageListener = listener;
            break;
        case 2:
            // First Fragment of Third Tab
            result = new Reports();
            break;
        default:
            result = null;
            break;
    }

    return result;
}

Also make sure to call it like this in your onClick

Alerts.secondPageListener.onSwitchToNextFragment();
M G
  • 1,240
  • 14
  • 26
0

you can try this. for tab2 fragment create xml file like this:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/main"> <!-- this line is the most important part-->
   <!-- your other layout s or views go here-->
</FrameLayout>

or just set id to your topest layout in you frag xml and and use it as container id in java code.

then in your fragment code in where you try to call interface to switch fragment just do that:

 getChildFragmentManager().beginTransaction().replace(R.id.main, destfragment).addToBackStack("youtag").commit();
Ali mohammadi
  • 1,839
  • 26
  • 27