In my app, I want to test button background is correct with what I expect. But I get Nullpointerexception error when try to get button background. I can not see where I wrong.
My code below:
Button btnGetStarted = (Button) getActivity().findViewById(R.id.btnGetStarted);
Drawable actual = btnGetStarted.getBackground();
Drawable expect = getActivity().getResources().getDrawable(R.drawable.btn_active_normal);
assertTrue("Wrong button background", actual==expect);
Nullpointerexception at line `Drawable actual = btnGetStarted.getBackground();
I can not solve it after 2 days so I post it on here to looking for help.
Edit:
In xml file I set button background from a picture btn_getstarted.png like this: android:background="#drawable/btn_getstarted"
Your button is null here. That's why you are not getting the drawable.
Change the code in your test case like this and try :
private View inflaterView;
LayoutInflater i=(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflaterView=i.inflate(R.layout.you_layout_file, null);
Button btnGetStarted=(Button) inflaterView.findViewById(R.id.btnGetStarted);
Addition to this I think comparing two drawable like this is not the correct way.
If both variables contain references to objects that 'look' the same, they are two different objects instances.So two drawable objects, will not return true on equals.
As a suggestion to test two drawable objects get the constantState associated to that Drawables.
btnGetStarted.getBackground().getConstantState.getConstantState().equals
(getResources().getDrawable(R.drawable.btn_getstarted).getConstantState())
Check, that you button id in xml is "#+id/btnGetStarted". Try to inflate your layout by LayoutInflater and find your button with View.findViewById()
Related
I am integrating Card.IO library in my android project and I wanted to know a way to change CardIOActivity header and button background colors.
I have tried following
LayoutInflater inflator = (LayoutInflater)getSystemService(CardIOActivity.LAYOUT_INFLATER_SERVICE);
I wanted to inflate a view from this inflator and change the color then.
However, I don't know the name of header xmls and button xmls.
How do I change these respective background colors?
I don't know what you are actually looking for but if you are in same activity then you can try this.
View root_view = this.findViewById(android.R.id.content).getRootView();
above statement will give you root view. Now you need to search all children in this view.
for(int i=0; i<((ViewGroup)v).getChildCount(); ++i) {
View nextChild = ((ViewGroup)v).getChildAt(i);
try {
// IF TYPECAST SUCCESS THEN YOU CAN USE BUTTON FOR YOUR PURPOSE. YOU CAN USE RECURSION FOR YOU PURPOSE.
Button button = (Button)nextChild;
// HERE YOU CAN APPLY BACKGROUND FOR YOU BUTTON.
button.setBackgroundColor(Color.GREEN);
} catch (Exception e) {
}
}
The above code is just an idea how you can try to access the button. You actually need to write recursive function to get child views for all childs till child count is 0.
am new to android
I have seen many examples on creating buttons, but i just can't get what does each line mean :(
take the following piece of code as an ex.
connect = (Button) findViewById(R.id.button_connect)
connect.setOnClickListener(connectListener)
private OnClickListener connectListener = new OnClickListener() {
public void onClick(View v) {
Log.i("CONNECT PRESSED", "press")
// ....
// ....
// ....
};
what i know is that the first line Defines a button, but wht is findViewbyId?
i know the second line
but then when defining the listener, what's the log.i?
nd r "connect pressed" and "press" just labels for the button? f so why there r two for a single button...
You should have an additional Button connect; before those lines.
connect = (Button) findViewById(R.id.button_connect) // findViewById() in layman term it means, finding view by id. Which also means finding the view(button/textview/edittext) by ID(value you stated in your main.xml for the view. e.e. android:id=#+id/"")
connect.setOnClickListener(connectListener) //listens to a click when clicked
private OnClickListener connectListener = new OnClickListener() { //if button of android:id="button_connect" is clicked, Do this method.
public void onClick(View v) {
Log.i("CONNECT PRESSED", "press") //prints message in your logcat
// ....
// ....
// ....
};
If you still don't understand what does findViewById(), just think of it this way. View is man. Id is name. So in the end you are finding the man by name("Whatever this is")
In Android you normally define the layout of an Activity in an XML file. Each View element in a layout that you want to interact with in code needs an id. In you example the layout XML file needs to have a button with the id button_connect.
In the onCreate() method of an Activity you normally call setContentView() and pass it the layout you want to use in this Activity. E.g. setContentView(R.layout.my_layout); where your layout file's name is my_layout.xml.
The setContentView() method builds up the defined layout as objects and with findViewById(R.id.button_connect) you get a reference to a Button object from this layout whose id is button_connect.
Log.i() is simply logs the message "press" under the tag "CONNECT PRESSED" in the log cat.
It seem to be you didn't read basic things about android app development. Android Developers website providing information to learn android app development with good examples and tutorials. You are asking very basic things by just copying the code from tutorials.
Actually its not the right place for this kind of questions. First do practice by reading tutorials around the web.
Coming to your doubts regarding code you posted here, those are very basic things.
findViewById() finds a View by field Id, which is declared in XML layout file as below
Log.i() is LogCat info message displayed in your logcat window when debugging is enabled in your app.
in your example you probably have defined an xml layout file as the style of your activity with setContentView(R.layout.myXMLLayout);
If not, findViewById(R.id.button_connect) will fail.
R.id.button_connect refers to an id created in your xml layout.
There has to be a line android:id="#+id/button_connect" in a < Button > tag.
findViewById finds this Button (which is more genereally a view, which is why you have to cast it to a Button with the (Button) before findViewById(...) ). You then refer to exactly the button you've put in your xml.
Log.i("CONNECT PRESSED","press"); isn't necessary at all. It's just logging the press of the button and displays it in the log cat. It can be removed without any further impact. This is for debugging only and should be removed for any final (public) versions of your code.
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">
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);
Try to use the method setTag() , and then you can get all your ToggleButton by using : findViewByTag();
Perhaps tb is null? Could you check that out?
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.
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.
I'm new to Android and find it brutal (there seems to be an near infinite number of details and dependencies to remember).
Anywho, I got the TextSwitcher1 example app working, which uses ViewSwitcher. I'm assuming ViewSwitcher is the way to go, need to either display a map or a table, user can pick, and switch back and forth.
So I created my MapActivity in another application, seems to work. Next integrate into main app. So, call
View v = findViewById(R.layout.mapview);
and then
mSwitcher.addView(v);
except "v" is null. Why? Do I create the activity? But I don't want to show it yet. Is there such a call as "create activity but hide it until needed"? Or am I barking up the wrong tree?
Thanks for any insight.
The findViewById function returns a View based on an ID resource (R.id.something) for whatever view you have loaded in your activity (using setContentView(R.layout.main)). In your sample code, you're using a layout resource (R.layout.mapview). You should inflate the XML file, which will return a View that you can use to add to the ViewSwitcher.
Example Code:
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.mapview, null);
mSwitcher.addView(v);
However, you should be able to define everything in your XML file and not have to manually add the pages to your ViewSwitcher. Here's some example code on how to do that: http://inphamousdevelopment.wordpress.com/2010/10/11/using-a-viewswitcher-in-your-android-xml-layouts/
TextView txtOtherMatches = (TextView) dialog.findViewById(R.id.txtOtherMatches);
txtOtherMatches.setText("Other Matches");
i m getting this error while running application and i m just assigning simple text to Textview at run time .....
java.lang.NullPointerException
Make sure your TextView in the xml has exactly the same id: android:id="#+id/txtOtherMatches"
Check that you don't have more than one res/layout folder (e.g., layout-normal, layout-large or layout-land) and, if you do, make sure that your TextView is present in the layourt corresponding to your device/emulator
Check that it was added to the current View (most probably, through some ViewGroup)
If everything else fails, clean the Eclipse project and rebuild
txtOtherMatches is probably null because it doesn't exist in the current view.When you use findViewById the view must be in the "contentview" you've set with setContentView, or added later tot the view. You can't find any "random" view that has an ID somewhere, it must actually be "present" in your current view.
If the view is NOT in the xml you're using already, but somewhere else in one of your xmls, you must use an inflater to get the View, and add it with View.add()
It would be helpfull if you provide a few more lines before that one.
But my guess is Nanne is right.
Try to add a safety check:
(this wouldn't change the code flow)
if(txtOtherMatches == null) {
throw new NullPointerException("darn, the R.id.txtOtherMatches is not in the dialog")
}
(on the other hand Nanne mistakenly mentions 'current view' while I'm sure he meant the 'dialog' view.
Put some more meat if you need further assistance ;)