user3217789
user3217789

Reputation: 211

nullpointer running method of fragment from activity when using views

My Fragment

public class CustomFrag extends Fragment {

    private Button btn;

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

        btn = (Button)view.findViewById(R.id.button1);

        return view;
    }
    public void sendItem(String item) {
        btn.setText(item);
    }
}

And in my activity

public void loadFragment(String data) {
    // Load up new fragment
    Fragment fragment = new CustomFrag();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();

    transaction.add(R.id.contentFragment, fragment, "custFrag");
    transaction.addToBackStack("custFrag");
    transaction.commit();

    // Required before calling fragment methods 
    getSupportFragmentManager().executePendingTransactions();

    // Load fragment with data
    CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
    frag.sendItem(data);
}

I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work

i.e. inside sendItem()

btn = (Button)getView().findViewById(R.id.button1);

My layout (button_fragment) contains the button:

<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Upvotes: 0

Views: 34

Answers (2)

0101100101
0101100101

Reputation: 5911

The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):

public class CustomFrag extends Fragment {

    private Button btn;

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

        btn = (Button)view.findViewById(R.id.button1);
        btn.setText(getArguments.getString("item"));
        return view;
    }
}

And

public void loadFragment(String data) {
    // Load up new fragment
    Fragment fragment = new CustomFrag();
    Bundle args = new Bundle();
    args.putString("item", data);
    fragment.setArguments(args);

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();

    transaction.add(R.id.contentFragment, fragment, "custFrag");
    transaction.addToBackStack("custFrag");
    transaction.commit();

    // Required before calling fragment methods 
    getSupportFragmentManager().executePendingTransactions();
}

Edit: njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.

Upvotes: 1

njzk2
njzk2

Reputation: 39406

Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.

To pass data from the activity to the fragment, use the argument bundle:

Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);

Then, in onCreateView:

btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));

See this Best practice for instantiating a new Android Fragment question and the first answer.

Upvotes: 2

Related Questions