I'm getting null pointer exceptions when I try to initialize Button and EditText objects in global scope, can't figure it out. I've commented out everything but the bare minimum for the app to display my layout, but this still causes a crash:
private EditText addmoney = (EditText)findViewById(R.id.addmoney);
R.id.addmoney definitely, definitely exists. So what the heck? Is it impossible to declare EditText in global scope? I need to be able to call it from both onCreate and onPause in a class extending Activity, is there maybe another way I should be doing this?
EDIT:
I tried using shade's method of inflating the layout first but it causes errors, apparently your not allowed to use system services before onCreate() has been called and inflating a view requires one.
You have to execute findViewById only after you have set the content for your current activity.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
addmoney = (EditText)findViewById(R.id.addmoney);//it knows in which file to search for the id
}
Alternatively, you could do something like this:
private View dummy = (View) View.inflate(this, R.layout.dummy, null);
private EditText addmoney = (EditText) dummy.findViewById(R.id.addmoney);
... and in the onCreate (or wherever else):
setContentView (dummy);
Since you already have the parent of the EditText view instantiated, you can reference it without having a NPE.
NOTE: The first parameter of inflate is a Context. Therefore, you need a Context that is alive for this to work.
Ooops, wrong class :D
Related
I need show a TextView in all Activities, but is much work to do it one by one, because I have +10 Activities.
My objective is when I click in a button, show a textview ("Importing ...") at the bottom of the application. This textview will disappear when I receive a push notification, and I owe a pop up with the response (the pop up also has to appear in any activity).
My project has a custom abstract BaseActivity and all activities extends it.
public abstract class BaseActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected void setActionBar(#IdRes int idResToolbar) {
Toolbar toolbar = (Toolbar) findViewById(idResToolbar);
setSupportActionBar(toolbar);
updateFont(toolbar);
}
// ...
}
I think I could use for my purpose but not how to do it.
If anyone has any suggestions I will be happy to hear it.
Thanks in advance.
Use fragments for your content (instead of different activites) you then can add global views to the activity, which holds the fragments.
If you don't want to do that, you'd have to modify the layout(s) in your Base class.
I would suggest you to use a PopupWindow that contains the text view and create a separate class that initializes the PopupWindow on the basis of context given to it.
Now in all your Activities you will have the control of showing and hiding the window as you want. Make sure to make all utility methods required in the separate class to avoid coherence for example hiding and showing the window. setting text of text view of the window and etc.
You can write in onCreate() of your base activity something like
setContentView(R.layout.base_layout);
And in every other Activity at start of onCreate() method, just use super.onCreate()
And more than that to support different layouts add something like this in onCreate() (example for one of activities)
LayoutInflater inflater = getLayoutInflater();
inflater.inflate(R.layout.activity_1_layout,rootGroup)
where rootGroup is a ViewGroup in your Base Activity, in which you will add additional components for every other activity
Create a service, which creates a View which can be drawn over other apps (will require the relevant permission in the manifest)
You could use one of the open source libraries available like this or refer to this example
It's better you use fragments instead of using many activities. However, if you don't wanna do so, I suggest you create a factory which will generate a textview to all activities. Then you must add it into each activity's view.
I am making an app using two tabs with different layouts, which means I have three total layouts at the moment:
activity_main,
fragment_receive,
fragment_send
In my onCreate method in my main activity, the following line sets my content view to activity_main. (If anyone could explain why this layout appears to be blank and yet my app still shows both tabs, that would be great.)
setContentView(R.layout.activity_main);
Then I use the findViewById method to set a TextView to a view that appears in both fragment_receive.xml and fragment_send.xml.
currentExchangeRate = (TextView) findViewById(R.id.exchangeRateView);
Then I attempt to use the setText method on this TextView.
currentExchangeRate.setText(Double.toString(lastPrice));
This line gives me the NullPointerException.
Can anyone explain this to me?
findViewById() called from the Activity, looks for the id in the hierarchy of views of the Activity.
if you want to perform that on the Fragment hierarchy, you have to call it from the Fragment view, for example view.findByById() from the Fragment onCreateView, after you inflated the layout.
When you call:
currentExchangeRate = (TextView) findViewById(R.id.exchangeRateView);
The compiler finds that the static int ID does exist within your R.id because you declared them in your fragments, and therefore doesn't throw a compiler error. But at runtime, the current view layout (the one you set with setContentView(R.layout.activity_main);) doesn't hold that ID and therefore returns null.
To access your textview that exists within your Fragment from the Controlling Activity, you use the Fragment Manager (add an id property to your fragments in activity xml, or set tags when you declare your Fragments in your code):
ReceiveFragment receiveFragment = (ReceiveFragment) getSupportFragmentManager().findFragmentById(R.id.receive_fragment);
TextView tv = (TextView) receiveFragment.getView().findViewById(R.id.exchangeRateView);
tv.setText(Double.toString(lastPrice));
findViewById retrieves the view with the requested id from your activity's layout
To get your fragment's textview, make the view that your fragments onCreateView is returning a static variable and initialize it in the onCreateView.
Then you can retrieve the textview like this:
TextView textview = (TextView) YourFragmentTitle.yourFragmentViewTitle.findViewById(R.id.yourId);
Everything in my Activity is working fine. I'm able to load all the values fine and show in every EditText except one. The sequence of the actions on onCreate is
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.rule_editor);
initComponents(); //references all private objects to each object in activity layout
populateCategorySpinner(); //populates a category spinner
loadRule(); //loads the rule from a singleton on the basis of an extra data passed from parent activity
attachEvents(); //attaches event to each object
Log.d("", txtIdentifierString.getText().toString());
}
The problem is in one of the EditText. The reference in code is txtIdentifierString. The values that I set (by setText()) on it is not showing up in activity on runtime.
Logcat shows up a value from the Log.d method call in last line of the onCreate method, but its not visible in the EditText txtIdentifierString. The EditText box is visible, I can focus on it and type in a value as well.
Does anyone has any idea about it?
I'm answering my own question.
I debugged the codes and found out that OnItemSelectedListener on a spinner had to reset the EditText in question. The change is triggered before I Logged the value
I have two classes that extend the activity class. Each class has it's own layout class, main.xml and compose.xml.
In my main activity I try to access a layout element that is in compose.xml. So:
EditText smsBody = (EditText)findViewById(R.id.smsBody);
But smsBody is null. Why? How can I access it?
Did you set the content view in the onCreate() method?
Like in this example:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Well, your main activity has a main.xml layout. Your compose activity has a compose.xml layout. Assuming your "smsBody" EditText is in the compose.xml layout, then this will be only accesible in your compose activity, since that widget doesn't exist in your main.xml layout.
when main activity have layout main.xml, how you can expect that you can access component of compose.xml ?? you suppose to play with view inside layout you set using setContentView() .
in exceptional cases we need to use other layouts as well , so you can use LayoutInflater for this
newSubmitButton = (Button) findViewById(R.id.newPlayerSubmit);
Log.v("heeelp",""+newSubmitButton);
Seems simple enough. I have a global Button variable called newSubmitButton. I fetch the Button from an xml file in the project (I promise, the button exists, i didn't mispell the name, etc.) I output the button in the next line, it is null. I try to give it an onClickListener and it throws a null pointer exception. How is this button null? I just instantiated it the line before!
I just instantiated it the line
before!
No you didn't,
newSubmitButton = (Button) findViewById(R.id.newPlayerSubmit)
does not instantiate anything. It simply retrieves the button from the active view. If the button isn't part of the active view (perhaps the layout hasn't been inflated yet?) then your button reference will be null. Are you calling this code in your Activity's onCreate() method? Have you called setContentView() before executing the code in question?
Besides misspelling the name, you might have left out a call to setContentView().
(If that's not the issue, please post more code.)
Did you remember to setContentView() higher up? Just because R.java contains it doesn't mean it's attached to your view.