NullPointerException, can't get my textview from my layout

Question!

Edit: Answered my own question.

My textView is null and I don't understand why. I use a personal fragment manager maybe it's the problem. My Id is correct because if I add the fragment on the main activity and change the text from the fragment onCreate method the change text function works. What does not work is that I have a fragmentA that is added to my activity, I click on a button and count the number of time I click on it. Then I wanna change the Textview of my FragmentC to " the counter is equal to .." and ONLY then my textview is null. I suspect the reason for it to be null is that it's not yet added to the activity. So the onCreateView is actually not called. Any way I can fix that ? Should I call Fragment.OnCreateView in my respond function ?

My class with the textview:

public class FragmentC extends Fragment {
    TextView textView;
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragmentc, container,false);
        //textView = (TextView) view.findViewById(R.id.txtinfo2);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        textView = (TextView) getActivity().findViewById(R.id.txtinfo2);
    }

    public void changeText(String str){
        if(textView==null)
            Log.e("truc", "null txt");
        textView.setText("jghjh");
    }
}

Log gives txt null

fragmentc.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#854f98be">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment C"
        android:id="@+id/txtinfo2"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

I put the rest of code because I have my own FragmentManager and may be the problem comes from there:

My MainActivity:

public class MainActivity extends ActionBarActivity implements Communicator{

    private MonFragmentManager monFragmentManager;
    public static final String TAG="truc";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        monFragmentManager = new MonFragmentManager
                (getSupportFragmentManager(),R.id.container,new FragmentA(),new FragmentB(), new FragmentC());
        monFragmentManager.add(1, false);
    }
    @Override
public void respond(String data) {
    FragmentC frag = (FragmentC) monFragmentManager.getFragments()[2];
    if(frag.getClass()==FragmentC.class)
        Log.e("truc","fragment correct");
        //log gives "fragment correct".
    frag.changeText(data);
}
}

MyOwnFragmentManager class:

public class MonFragmentManager {
    private FragmentManager fm;


    private Fragment[] fragments;
    int container;

    public MonFragmentManager(FragmentManager fm){
        this.fm = fm;
        fragments = fm.getFragments().toArray(new Fragment[fm.getFragments().size()]);
    }
    public MonFragmentManager(FragmentManager fm, int container,Fragment...frags){
        this.fm = fm;
        this.container=container;
        fragments = new Fragment[frags.length];
        for(int i=0;i<fragments.length;i++){
            fragments[i]=frags[i];
        }
    }

    public void hideAllFragments(){...}

    public void showFragment(int fragmentIndex, boolean addToBackStack) {...}
    public void add(int fragmentIndex, boolean addToBackStack){
        FragmentTransaction transaction = fm.beginTransaction();

        for (int i = 0; i < fragments.length; i++) {
            if (i == fragmentIndex) {
                transaction.add(container,fragments[i]);
            } else if(fragments[i].isAdded()) {
                transaction.remove(fragments[i]);
            }
        }
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.commit();
    }
    public void removeAllFragments(){
        FragmentTransaction transaction = fm.beginTransaction();
        for(int i = 0; i < fragments.length; i++) {
            transaction.remove(fragments[i]);
        }
        transaction.commit();
    }
    public Fragment[] getFragments() {
        return fragments;
    }
}
By : mushmuch


Answers

It is safer to do the findViewById() in onViewCreated method.

Sample code:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    textView = (TextView) view.findViewById(R.id.txtinfo2);

Notes:

  • With onViewCreated, the View parameter is supplied, that is the only hint.
  • I realize you're using onActivityCreated method because it is triggered after onCreateView. But I believe upon my experience, not from documentation, that the View may not yet be ready for use. You can test this behavior by rotating the screen.


The problem is that my fragment is not added to my activity (I didn't define the fragments in my activity layout). An easy fix is just to add them all to the activity layout and use hide/show instead of add/remove.

By : mushmuch


This video can help you solving your question :)
By: admin