7

I have a BlankFragment

package com.hfad.addingafragmenttoframelayout;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.w3c.dom.Text;


/**
 * A simple {@link Fragment} subclass.
 */
public class BlankFragment extends Fragment {


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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d("message","onCreateView() of BlankFragment");
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }

    public void setText(String textToBeSet){
        TextView tv = (TextView)this.getView().findViewById(R.id.fragmentText);
        tv.setText(textToBeSet);
    }

}

and it's layout is:

<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"
    tools:context="com.hfad.addingafragmenttoframelayout.BlankFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment"
        android:id="@+id/fragmentText"/>

</FrameLayout>

Here is the MainActivity

package com.hfad.addingafragmenttoframelayout;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //BlankFragment bf = new BlankFragment();
        //getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, bf).commit();

        BlankFragment bf = new BlankFragment();
        bf.setText("hello world");
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, bf).commit();


    }




}

and here is the layout of MainActivity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.hfad.addingafragmenttoframelayout.MainActivity"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fragment_container"
        />


</LinearLayout>

In the onCreate method of activity I am adding fragment to layout. This works fine unless I try to change the Text using setText method.

And I get this error:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
                                                                                           at com.hfad.addingafragmenttoframelayout.BlankFragment.setText(BlankFragment.java:35)
                                                                                           at com.hfad.addingafragmenttoframelayout.MainActivity.onStart(MainActivity.java:29)

referring to this line

TextView tv = (TextView)this.getView().findViewById(R.id.fragmentText);

Can somebody explain what's causing this exception?

2
  • 2
    Possible duplicate of Nullpointer exception Commented May 12, 2016 at 5:30
  • 1
    Try use bf.setText("hello world"); after you've done getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, bf).commit(); Commented May 12, 2016 at 5:34

6 Answers 6

24

Don't

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.d("message","onCreateView() of BlankFragment");
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_blank, container, false);
}

public void setText(String textToBeSet){
    TextView tv = (TextView)this.getView().findViewById(R.id.fragmentText);
    tv.setText(textToBeSet);
}

Do

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
{

    View RootView = inflater.inflate(R.layout.fragment_blank, container, false);
    
    TextView tv = (TextView)RootView.findViewById(R.id.fragmentText);
    tv.setText("HI");
    
    return RootView;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I get your point, but thing is as I am creating BlankFragment's object myself hence onCreateView isn't called. Is there a way to call Fragment's life cycle method while instantiating object?
1

Here:

bf.setText("hello world");

line causing issue, becuase calling setText method of Fragment before adding Fragment in FragmentManager.

Call setText method after adding bf Fragment:

    getSupportFragmentManager().beginTransaction().
    add(R.id.fragment_container, bf).commit();
    bf.setText("hello world"); // call here

1 Comment

This did not make any difference. I am getting the same error.
1

The problem is FragmentTransaction is async by default

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_container, BlankFragment.newInstance);
ft.disallowBackStack();
ft.commitNowAllowingStateLoss();

Then you still can't get the Fragment yet, you have to get it from the FragmentTransaction

BlankFragment bf = (BlankFragment) getSupportFragmentManager().getFragmentById(R.id.fragment_container);
bf.setText("hello world");

This article helped me to understand this problem better

1 Comment

Thanks, but it's about commitNow(), not commit(). In your case, you are right, a problem in setting a text too early. You should set it in onCreateView() or onViewCreated() of a fragment.
0
TextView tv = (TextView)this.getView().findViewById(R.id.fragmentText); 

do it in onCreateView();

Comments

0

You can use a temporary variable that can hold the String while the View is not yet created.

private TextView tv;
private String holder = ""; 

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_blank, container,false);

    tv = (TextView)v.findViewById(R.id.fragmentText);
    return v;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
   tv.setText(holder);
}

public void setText(String textToBeSet){
    if(tv != null){
       tv.setText(textToBeSet);
    }else{
       holder = textToBeSet;
    }
}

Comments

0

My assumption is that you want to instantiate your BlankFragment with some initial text as well as allowing the text to be set later on from your MainActivity.

In that case I would first change the the Fragment to accept an initial text like so:

public class BlankFragment extends Fragment {
    private static final String ARG_INITIAL_TEXT = "arg_initial_text";

    public static BlankFragment newInstance(CharSequence initialText) {
        final BlankFragment fragment = new BlankFragment();
        final Bundle args = new Bundle();
        args.putCharSequence(ARG_INITIAL_TEXT, initialText);

        fragment.setArguments(args);
        return fragment;
    }

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

    private CharSequence mInitialText;
    private TextView mText;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mInitialText = getArguments().getCharSequence(ARG_INITIAL_TEXT);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d("message", "onCreateView() of BlankFragment");
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mText = view.findViewById(R.id.fragmentText);

        mText.setText(mInitialText);
    }

    public void setText(CharSequence textToBeSet) {
        mText.setText(textToBeSet);
    }
}

The Activity code would then look like the following:

public class MainActivity extends AppCompatActivity {
    private BlankFragment mBlankFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            final Fragment bf = BlankFragment.newInstance("hello world");
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment_container, bf, BlankFragment.class.getName())
                    .commit();
        }

        mBlankFragment = (BlankFragment) getSupportFragmentManager()
                .findFragmentByTag(BlankFragment.class.getName());
    }

    private void someTimeLaterWhenWantingToSetNewTextToFragmentFromActivity(CharSequence newText) {
        if (mBlankFragment != null) {
            mBlankFragment.setText(newText);
        }
    }
}

Note that the null-check of savedInstanceState is to guard for Activity-recreation for instance due to configuration changes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.