user1033558
user1033558

Reputation: 161

android setBackgroundColor in runtime and other general confusion help?

i have a row of buttins created like this i want to change the background colour at runtime in code.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

LinearLayout track1 = (LinearLayout)findViewById(R.id.my_toggle_container); 

for (int i = 0; i<32; i++) {
        ToggleButton tgl = new ToggleButton(this);
        tgl.setId(i);
    ...
track1.addView(tgl);

this names the id of the togglebuttons 1, 2, 3... (i presume?) i have an int variable called 'xBtn' that changes 1, 2,.. this is how i get a reference to the button using xBtn

String buttonID = ""+xBtn;
            int resID = getResources().getIdentifier(buttonID, "id", "com.thing");
            //find the button
            ToggleButton tb = (ToggleButton) findViewById(resID);
            //change its colour
            tb.setBackgroundColor(Color.BLUE); 

it crashes on the setBackgroundColor line.

it may be obvious to someone whats wrong and thats what im hoping any help would be totaly ace ta thanks

main.xml

<LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/my_toggle_container" android:orientation="vertical">

Upvotes: 1

Views: 1047

Answers (5)

LuxuryMode
LuxuryMode

Reputation: 33741

The id of your togglebuttons is gonna be a number from 1 to 32... However, trying to find the toggle button by id will return null because simply instantiating a new toggle button and giving an id wont help you. findViewById looks in the parent view for a child view with the specified id. If you havent added that toggle button with that id to the view, then findViewById will return null. I am 99.99% sure even without looking at the log, that it crashes because you are calling setBackgroundColor on a null object.

In other words, the id that you set a view to is only relevant once the view is actually added to a parent view. In your case you are probably trying to add these toggle buttons to your main content view, in which case you need grab hold of that view that you used for setContentView and call addView on that view and pass in each new toggle button. Note that this will probably not look right unless you also specify layoutparams for the togglebuttons.

EDIT

If thats your entire main.xml, then you've got other issues. Post the full xml file. In any event, you still are going to have to do what I've said, which is to grab hold of the view or a child view of that view and then add the toggle buttons to it via addView (after giving the togglebuttons their proper ids). Once the button has been added, then you can find it. Note though that if you're gonna add the toggle buttons to a child view of your main view, then you'll likely have to grab hold of that child view and call findViewById on THAT.

For example, you can do a nested call like this. findViewById(1) <--- gets you the LinearLayout or whatever inside of your main content view, then once you have that you can call addView on it. So LinearLayout ll = (LinearLayout)findViewById(someNumber); ll.addView(tb);

Upvotes: 1

Houcine
Houcine

Reputation: 24181

Try to use the method setTag() , and then you can get all your ToggleButton by using : findViewByTag();

Upvotes: 0

WSBT
WSBT

Reputation: 36323

It's very likely that tb is null, because findViewById() didn't go as you expected.

You can verify this by surrounding the erroneous line with try.. catch block:

try {
    tb.setBackgroundColor(Color.BLUE); 
} catch (Exception e){

}

and watch for the message of e. It's likely to be null pointer exception.

In fact, I think you should not use getResources().getIdentifier(buttonID, "id", "com.thing") in the first place. It seems to me that all these resources are continuously numbered in R file, thus you should simply get the first id (as an integer), and then increment on that.

That is, you should do things like:

// The following code is not tested; I just wrote it here on SO.
for (int resID = R.id.button1; resID <= 32; resID++) {
    ToggleButton tb = (ToggleButton) findViewById(resID);
    tb.setBackgroundColor(Color.BLUE); 
}

this should make all 32 buttons blue.

Upvotes: 0

Yevgeny Simkin
Yevgeny Simkin

Reputation: 28349

To expand on what LuxuryMode said... What gets an ID INTO your java is inflating it via setContentView and setting it as content. That's why it's ok to have overlapping (duplicate) IDs in different layouts. You can have @+id/submit_button in layout1.xml and in layout2.xml and the Activity will get you the object via findViewById(R.id.submit_button) based on which one you have loaded into setContentView() at any given moment.

So, we're all guessing that you're probably not setting the content view and hoping that the code will find your object in your non inflated XML, which it won't. Which would lead (as everyone has guessed) to you now dealing with a null object, which you obviously can't set a background color on.

I know it gets confusing cause you have the XML RIGHT THERE!!! But the reality is that the xml isn't "alive". It's just stuff for you to look at until you have tasked the Application with inflating it and converting all of it into Android objects of some kind. A lot of the time this is done mostly transparently to you, so, it's easy to forget that none of these things really exist.

Upvotes: 0

user942821
user942821

Reputation:

Perhaps tb is null? Could you check that out?

Upvotes: 0

Related Questions