Can anybody tell me why this isn't working? I want it to load a specific layout depending on what page is loaded. The if clause seems to be faulty. It's always going to the else.
wordArray = getResources().getStringArray(resId);
int resIdBack = getResources().getIdentifier(wordArray[5], "drawable", "com.bobgle.libretto");
// If Background Image is dark use light theme, if not use dark theme.
if(wordArray[5] == "libretto"){
view = inflater.inflate(R.layout.activity_fragment_dark, container, false);
} else {
view = inflater.inflate(R.layout.activity_fragment_light, container, false);
}
When comparing strings in Java you should use the equals method.
When using equal is good to remember that it can cause nullpointer if the object you are using equals on are null (duh!) so if you got a fixed string, that can't be null always use that first.
"libretto".equals(wordArray[5]) //Can't cause nullpointerexception.
wordArray[5].equals("libretto") //Can cause nullpointerexception if wordArray[5] is null.
This SO question explains why that is the case.
Related
Since we don't have to cast anymore, I expected findViewById to return the correct type, but it doesn't seem to do that. I'm obviously making a very simple mistake here, can you point it out?
I have a TextView's ID (since I created it dynamically) and want to change the text size of that item, this snippet works fine:
TextView tmpView = findViewById(chain.getIngredientNameId());
tmpView.setTextSize(8);
But this one doesn't:
findViewById(chain.getIngredientNameId()).setTextSize(8);
So I assume I have to case it to TextView but none of my attempts seems to work (using () or <>), what obvious thing am I missing?
You should cast it if do not save to variable.
TextView tmpView = findViewById(chain.getIngredientNameId()); //TextVeiw
((TextView) findViewById(chain.getIngredientNameId())).setTextSize(8); // TextVeiw
findViewById(chain.getIngredientNameId()); // View
I am trying to choose between two different layouts based on a value of a certain parameter and set that layout for my class.Both the layouts are having the same ids of all the views.If we dynamically allocate ids to the views of the two layout wont there be a ambiguity?When i tried practically I am getting a null pointer exception.Is this null pointer because of this ambiguity only??Can anybody please help.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// condition can be from getIntent() or from SharedPreferences or whatever
if(condition) {
setContentView(R.layout.activity_main);
} else {
setContentView(R.layout.activity_main_2);
}
// If they have the same components, but different layouts only
// You can use it as usual with findViewById(R.id.view_id);
Button btnExample = findViewById(R.id.btn_example);
}
I could't understand well what you asked. If i'm correct you asking if you can use the same id for a view on different layouts.
Yes you can. Unless you try to inflate those two layouts at the same time. Then you will have a problem.
You need to narrow you error.
if(condition) {
setContentView(R.layout.activity_main);
} else {
setContentView(R.layout.activity_main_2);
}
When you set different views, it may cause null pointer exception when any of the view is missing between this layouts.
So you should make sure that your findViewById returns not null. OR just add check when you try to use this views in the code.
Advanced....
Anyway if you already know all these things and have enough experience with all these stuffs, Try the belw listed libraries it will help you a lot
https://github.com/JakeWharton/butterknife
https://github.com/roboguice/roboguice
You can avoid "repetitive, cumbersome boilerplate coding parts. Indeed, we should focus on logic, not on meta programming".
These will help you to avoid all these findViewById...stuffs and you can slim your code...less bugs!
I'm new to android, and I am getting a NullPointerException on the line with the if statement in this code, and I am not sure why. This code is in my onItemClick method for my gridview in which I stored a 2d array of ImageViews.
ImageView selected = (ImageView) grid.getSelectedView();
if(selected.getDrawable().equals(R.drawable.piecered2))
{
Toast.makeText(game.this, "red" , Toast.LENGTH_SHORT).show();
}
The app runs, but when I actually click on an item, it crashes, giving me a NullPointerException.
The documentation states Return the view's drawable, or null if no drawable has been assigned..
Do you have a drawable assigned? If not, you are calling the equals method of null within the if clause, which then causes the NullPointerException.
If you are sure, you have a drawale assigned, we could need more code here.
Putting aside your NullPointerException, the way you compare the things are wrong. Because .equals() method is used to compare the strings. Your R.drawable.piecered2 returns an integer value(id) which is generated in R.java. Your getDrawable() returns a Drawable object which can't be compared with an integer.
Coming to your NPE issue, clearly log the values of getDrawable() before you actually make use of them whether it contains null or the most convenient way to track these is to debug your code.
Assuming you have only ImageView in your GridView.
View v = grid.getChildAt(0);
if(v instanceof ImageView)
{
ImageView selected = (ImageView) v;
if(selected.getDrawable().equals(R.drawable.piecered2))
{
Toast.makeText(game.this, "red" , Toast.LENGTH_SHORT).show();
}
}
I am working on an application, and from a list view I create a bundle that includes the item selected and the previous item. What I need to determine is if the previous item actually gets bundled through. If it exists, I want the information, but if it doesn't exist, then I need to set my text views to reflect that. But I get a null pointer exception if it doesn't exist when trying to load the receiving activity (the bundling activity does not cause the crash as I found during debugging - I get to the point where I'm testing for the data in the bundle before it crashes). So I've included the code from the receiving activity.
Bundle evmBundle = this.getIntent().getExtras();
final EVMData evm = (EVMData) evmBundle.getSerializable("evm");
final Project project = (Project) evmBundle.getSerializable("project");
if (!evmBundle.getSerializable("prvEVM").equals(null)){
final EVMData prvEvm = (EVMData) evmBundle.getSerializable("prvEVM");
edtPrvAC = (TextView) findViewById(R.id.edtPrvEVMAC);
edtPrvAC.setText(prvEvm.getAc().toString());
}
else{
edtPrvAC = (TextView) findViewById(R.id.edtPrvEVMAC);
edtPrvAC.setText("0");
}
I know something is getting passed through in the bundle for "prvEVM" because it showed up as part of the bundle in the debugger.
I also tried pulling it out of the bundle first and then trying to compare it. After pulling it out of the bundle, prvEvm is null (looking at the variables in the debugger), so I thought something like this might work:
if (!prvEvm.equals(null)){
edtPrvAC = (TextView) findViewById(R.id.edtPrvEVMAC);
edtPrvAC.setText(prvEvm.getAc().toString());
}else{
edtPrvAC = (TextView) findViewById(R.id.edtPrvEVMAC);
edtPrvAC.setText("0");
}
But I get a NullPointerException because prvEvm is Null. So I tried flipping the if test around, but got the same results. I should note that no matter how I set this up, if prvEvm is not null, all configurations here work - the requested data is put in the TextView. Basically, I need to be able to get around this null pointer exception. I know the object is null, I want to test for that so that if it is, that object isn't used. It will only be null once.
Don't use equals(null) as you call a method (equals) on a null object. Instead, compare to null:
if (prvEvm != null){
besides, equals(null) always returns false.
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.