34

I'm having trouble adding a button to a layout that I've created in XML. Here's what I want to achieve:

//some class
else {
        startActivity(new Intent(StatisticsScreen.this, ScreenTemperature.class));
}
////

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

    //this is where I call another class that
    //displays a nice graph
    setContentView(new GraphTemperature(getApplicationContext()));

}

I want to add a Button to this new screen so that it'll appear below the graph. I've tried creating a LinearLayout view, then create a Button and add it to this view but I just get NullPointerExceptions..

Any help would be appreciated. Thanks

EDIT#1

Here's what I've tried using that created a NullPointerException and 'force close':

Button buybutton;
LinearLayout layout;

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

    setContentView(new GraphTemperature(getApplicationContext()));

    layout = (LinearLayout) findViewById(R.id.statsviewlayout);
    Button buyButton = new Button(this);
    buyButton.setText(R.string.button_back);
    buyButton.setLayoutParams(new LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
    layout.addView(buyButton);

}

And here's the logcat error:

ERROR/AndroidRuntime(293): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.weatherapp/com.weatherapp.ScreenTemperature}: java.lang.NullPointerException
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
ERROR/AndroidRuntime(293):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)

theres abviously more lines to do with this error in logcat, not sure if you want it?

EDIT#2

So i tried bhups method:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GraphTemperature GT = new GraphTemperature(getApplicationContext());             
    layout = (LinearLayout) findViewById(R.id.statsviewlayout);
    Button buyButton = new Button(this);
    buyButton.setText(R.string.button_back);
    buyButton.setLayoutParams(new LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
    layout.addView(GT); // line 27
    layout.addView(buyButton);       
    setContentView(layout);           
}

This method produced the same logcat error as above, NullPointerException, indicating it was something to do with line no. 27 which is the layout.addView line of code. Any ideas? Thanks again

Daniel Kutik
  • 6,997
  • 2
  • 27
  • 34
mmmbaileys
  • 1,233
  • 4
  • 18
  • 33
  • 1
    show us what you tried and the logcat you get running that, so we try to find out why you get npe. anyway consider creating a `screen_temperature.xml` layout and using that in `setContentView()`. you can add in xml your custom view by specifying the whole package too, instead of just the name (ie: ``) – bigstones Feb 05 '11 at 15:29
  • create a linear layout (ll) and add GraphTemp view object and button object to ll. Then set the content view of the activity to ll. i.e. setContentView(ll); – bhups Feb 05 '11 at 15:39

2 Answers2

34

If you just have included a layout file at the beginning of onCreate() inside setContentView and want to get this layout to add new elements programmatically try this:

ViewGroup linearLayout = (ViewGroup) findViewById(R.id.linearLayoutID);

then you can create a new Button for example and just add it:

Button bt = new Button(this);
bt.setText("A Button");
bt.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
                                    LayoutParams.WRAP_CONTENT));
linerLayout.addView(bt);
Alex Cio
  • 6,014
  • 5
  • 44
  • 74
32

This line:

layout = (LinearLayout) findViewById(R.id.statsviewlayout);

Looks for the "statsviewlayout" id in your current 'contentview'. Now you've set that here:

setContentView(new GraphTemperature(getApplicationContext()));

And i'm guessing that new "graphTemperature" does not set anything with that id.

It's a common mistake to think you can just find any view with findViewById. You can only find a view that is in the XML (or appointed by code and given an id).

The nullpointer will be thrown because the layout you're looking for isn't found, so

layout.addView(buyButton);

Throws that exception.

addition: Now if you want to get that view from an XML, you should use an inflater:

layout = (LinearLayout) View.inflate(this, R.layout.yourXMLYouWantToLoad, null);

assuming that you have your linearlayout in a file called "yourXMLYouWantToLoad.xml"

Nanne
  • 64,065
  • 16
  • 119
  • 163
  • Could you have a look at my second edit? I posted it pretty much the same time you posted this answer. I'm not too sure I understand. The layout "statsviewlayout" is declared in an xml, if thats what you're asking? – mmmbaileys Feb 05 '11 at 16:01
  • Ok just after seeing your addition there. Ill give that a go :-) thanks – mmmbaileys Feb 05 '11 at 16:03
  • You seem to be doing this still: ` layout = (LinearLayout) findViewById(R.id.statsviewlayout);` As long as your, by lack of a better word, current view on the screen (the thing you set in `setcontentview` does not containt this id, you cannot do this. As long as the xml that contains the 'statsviewlayout' is not set using `setcontentview` the 'findviewbyid` will return `null` – Nanne Feb 05 '11 at 16:04
  • haha, we're commenting/reading between each others revisions/additions it seems ;) – Nanne Feb 05 '11 at 16:04
  • Yeah! Ok so I've gotten rid of the "layout = (LinearLayout) findViewById(R.id.statsviewlayout);" line of code and changed it to what you said. It works, no errors or anything. Only problem is, as the graph takes up the whole screen of the device (i'm using an emulator), I'm not sure if the button is actually there below the graph..To fix this do I just change the linearlayout to a scrollview or what? Thanks again Nanne! Edit sorry, i meant add a scrollview to the linear layout.. – mmmbaileys Feb 05 '11 at 16:23
  • you could surround the whole piece with a scrollview. But to check out if your button is there, maybe use the hierarchy-viewer to check out and test? http://developer.android.com/guide/developing/tools/hierarchy-viewer.html – Nanne Feb 05 '11 at 16:27
  • no prob, don't hesitate to press the nice and green 'accept' checkmark if you think my answer helpt :) – Nanne Feb 05 '11 at 16:38