Fragment Tabs inside Fragment - Null pointer Exception

时间:2015-05-24 20:26:09

标签: java android android-fragments android-activity

Inside my MainActivity.java I'm implementing a material design navigation fragment. When I tap on one of the navigation options, a new fragment appears - I want that fragment split into two separate fragments which can be switched via. Tabs.

I create the initially-shown one of those two fragments inside MainActivity:

public void onNavigationDrawerItemSelected(int position) {
   // etc... 
   case 1: fragment = new OffersSentFragment();
} 

Then make a simple FragmentPagerAdaptor (I've cut out the irrelevant code for this question):

public class OffersFragmentPagerAdapter extends FragmentPagerAdapter {
    final int PAGE_COUNT = 2;
    private String tabTitles[] = new String[] { "Offers Made", "Offers Received" };
    private Context context;

    public OffersFragmentPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0: return OffersSentFragment.newInstance("Sent");
            case 1: return OffersReceivedFragment.newInstance("Received");
            default: return null;
        }
    }
}

Then I make the two Fragments which will be tabbed between (OffersSentFragment and OffersReceivedFragment), both of which are basically the same at this point (one of which is shown below).

My problem is that the line:

viewPager.setAdapter(new OffersFragmentPagerAdapter(getFragmentManager(), getActivity()));

in the onCreateView() method below causes a java.lang.NullPointerException - this method would usually work in an Activity (this tutorial is similar to my code but uses an Activity instead) but either getFragmentManager() or getActivity() seems to be probomatic in a fragment. What is causing this exactly?

public class OffersSentFragment extends Fragment {
    private static final String ARG_PARAM1 = "param1";
    private String mParam1;  
    private OnFragmentInteractionListener mListener;

    public static OffersSentFragment newInstance(String param1) {
        OffersSentFragment fragment = new OffersSentFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        fragment.setArguments(args);
        return fragment;
    }

    public OffersSentFragment() {
        // Required empty public constructor
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);
        // THE LINE BELOW IS THE NULL POINTER ERROR 
        viewPager.setAdapter(new OffersFragmentPagerAdapter(getFragmentManager(), getActivity()));

        SlidingTabLayout slidingTabLayout = (SlidingTabLayout) getActivity().findViewById(R.id.sliding_tabs);
        slidingTabLayout.setDistributeEvenly(true);
        slidingTabLayout.setViewPager(viewPager);
        return inflater.inflate(R.layout.fragment_offers_made, container, false);
    }

    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

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

    public interface OnFragmentInteractionListener {
        public void onFragmentInteraction(Uri uri);
    }
}

1 个答案:

答案 0 :(得分:0)

I believe the issue lies with the following line:

ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);

Because you're trying to find the 'R.id.viewpager' in your activity. To do this, you would have to, in your activity, to call 'setContentView()' with an xml file that has a in the xml.
My guess is that you don't have this?
Because that would mean your viewPager variable would be null, and that would cause the NullPointerException.

----- EDIT AFTER COMMENT -----

Then you need to find the 'R.id.viewpager' on the layout you're inflating, and not the activity's layout.
Like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_offers_made, container, false);
    ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
    viewPager.setAdapter(new OffersFragmentPagerAdapter(getFragmentManager(), getActivity()));

    SlidingTabLayout slidingTabLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
    slidingTabLayout.setDistributeEvenly(true);
    slidingTabLayout.setViewPager(viewPager);

    return view;
}

This will find both the ViewPager and the SlidingTabLayout on the view you're inflating, which should work as you wanted.