Natalie Natalie - 7 months ago 46
Java Question

Null Pointer Exception for LayoutInflater inflater and ViewGroup container

I am making an app that creates an ImageButton every time the user does a certain action. So my button creation in dynamic.

I have a method (createButton) inside a FRAGMENT class that gets passed an image (which is used as the background of my ImageButton).

My problem is that I seem to need to use "LayoutInflater inflate" and "ViewGroup container" in order to open my relative layout view and add a dynamic button to it, but I am also passing an image this method, so my method is forcing me to initialize inflate and container.

I can't initialize them to null because then I get a NullPointerException when I run my app. I also try to pass them from onCreateView (like my code below), but I still get a NullPointerException. How can I use LayoutInflater inflate and ViewGroup container (without initializing them to null) while still passing other variables to my method. I am getting thrown the exception before "tag-name: rLayout" gets printed.

public class HomeFragment extends Fragment {

ViewGroup rootContainer;
LayoutInflater rootInflater;




@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

}

// onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);


rootContainer = container;

rootInflater = inflater;

return view;
}



// Create button from icon and image name

public void createButton (BitmapDrawable bitmapdrawable, String applicationName){

Log.d("tag_name", "createButton");

//LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
//(Context.LAYOUT_INFLATER_SERVICE);

try {


Log.d("tag_name", "Try_2");

// Get Layout home_fragment
View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);
RelativeLayout rLayout = (RelativeLayout) rootView.findViewById(R.id.home_fragment);
Log.d("tag_name", "rLayout");

// create image button with background as bitmapdrawable
ImageButton btn = new ImageButton(getActivity());
btn.setImageDrawable(bitmapdrawable);
int id = 1;
btn.setId(id);
Log.d("tag_name", "set the ID of the btn");

// create textview with applicationName
//TextView appName = new TextView(getActivity());
//appName.setText(applicationName);

// place new button next to existing button
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);


params.addRule(RelativeLayout.RIGHT_OF, id);
btn.setLayoutParams(params);

// place text under newly created button


// Put button and text in layout
rLayout.addView(btn);
//rLayout.addView(appName);
}

catch (Exception e){

System.out.println("Exception is "+e.toString());
}

}

}


Here is my stack trace:

05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: createButton
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: Try_2
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus I/System.out: Exception is java.lang.NullPointerException
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err: java.lang.NullPointerException
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err: at it.anddev.bradipao.janus.HomeFragment.createButton(HomeFragment.java:118)
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err: at it.anddev.bradipao.janus.MainActivity$1.run(MainActivity.java:155)


The line 118 in HomeFragment is this line:

View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);


The line 155 in my mainActivity is the second line here where I pass my variables to HomeFragment:

HomeFragment createbutton = new HomeFragment();
createbutton.createButton(bitmapdrawable, applicationName);

Answer

The problem is the way you create the fragment and call the createButton method over it

HomeFragment createbutton = new HomeFragment();
createbutton.createButton(bitmapdrawable, applicationName);

You cannot do this. All Activities, Fragments and Services in Android must go through their respective lifecycle so that they have a valid context attached to them.

By treating them as a normal Java class, you end up with a null context. As most methods in an Activity, fragments or service are called on its Context, you will get a null pointer exception, which is why your app crashes.

What you need !!

FragmentTransaction fragmentTransaction = getSupportFragmentManager()
        .beginTransaction();
Fragment profileFragment = new HomeFragment();//the fragment you want to show
fragmentTransaction
        .add(R.id.parent, profileFragment);//R.id.content_frame is the layout you want to replace
fragmentTransaction.commit();

This is how you create your fragment.

And for caling its createButton method you need an interface.

You will need to create an interface like this in you Fragment

public interface ButtonCreator{
    void buttonCreator(BitmapDrawable bitmapDrawable, String string);
}

And in your activity you will need to implement this method. Like this:

@Override
public void buttonCreator(BitmapDrawable bitmap,String a) {
    HomeFragment homeFragment = (HomeFragment)getSupportFragmentManager().getFragments().get(1);
    homeFragment.createButton(bitmap,a);
}

Don't forget to implement the interface like this

public class MainActivity extends FragmentActivity implements MenuFragment.OnMenufragListener, HomeFragment.ButtonCreator {

Also in your fragment you will have to get this in your onAttach method

private ButtonCreator bc;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    bc = (ButtonCreator) activity;
}

And you will call

buttonCreator(bitmapdrawable, applicationName);

instaed of

createbutton.createButton(bitmapdrawable, applicationName);

This will work. However I also see an error in your button implementation.

You will have to look into it.

  btn.setId(id);

Above line needs an id like R.id.something , not an integer. I am sure you will solve that.