I have a small problem releated to accessing data in other views so here is the code.
Button
Button button2 = FindViewById<Button>(Resource.Id.addExpereince);
Button Click
button2.Click += (sender, e) =>{
EditText addCompany = FindViewById<EditText>(Resource.Id.addCompanyName);
EditText addDate = FindViewById<EditText>(Resource.Id.addDate);
EditText addPosition = FindViewById<EditText>(Resource.Id.addPosition);
AddExpreince(1, addCompany.Text, addPosition.Text, addDate.Text);
SetContentView(Resource.Layout.Main);
};
I want to learn, how I can solve this problem. The button and EditText are on other views, and I actually don't need them to work in the main view, I just need the code to be initialized in the MainActivity so that they can be used in the other view.
The error I'm receiving for better reference:
System.NullReferenceException: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
You should use SetContentView() first, as per the document :
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
If you didn't add a layout to your Activity first, your Activity is basically an empty window. As a result, when you use FindViewById method you will get a NullReferenceException exception.
Solution :
Modify your code like this :
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button2 = FindViewById<Button>(Resource.Id.addExpereince);
EditText addCompany = FindViewById<EditText>(Resource.Id.addCompanyName);
EditText addDate = FindViewById<EditText>(Resource.Id.addDate);
EditText addPosition = FindViewById<EditText>(Resource.Id.addPosition);
button2.Click += (sender, e) =>
{
AddExpreince(1, addCompany.Text, addPosition.Text, addDate.Text);
};
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
im working the last days on a small app but since 2 days i cant set a text to my textview. I know that normally it has to be made in this way:
TextView textview1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview1 = findViewById(R.id.tvid1);
textview1.setText("blablabla");
}
In my case is my layout not directly the main layout where the textview is. Im using the default Navigation Drawer Example and their is another layout called that refers to the main-content-layout.
I let the program do something in another java-class and that class return a String Value that has to be displayed in my TextView. But I can get data from EditText-Field they are aswell in the same layout.
And this is the Error when my application has to set the text:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.TextView.setText(java.lang.CharSequence)' on a null
object reference
EDIT - 13.05.18 16:00:
when i put TextView calc_price_output into the onCreate methode and the textview set the text. But why he dont do it in another methode that use the same variable :?
PROBLEM SOLVED - But no idea how ...
the problem exists only in the last methode. All other works perfectly.
you need to call the function from oncreate method
private TextView calc_price_output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calc_price_output = findViewById(R.id.tv_calculate_price);
displayOutput("blablabla"); //call the function
}
//the string returns to this method
public void displayOutput(String spritprice){
calc_price_output.setText(spritprice);
}
you have not typecasted your object calc_price_output to hold a reference of textview reference.
just typecast it like this :-
calc_price_output = (TextView)findViewById(R.id.Tvid);
Edit : I suppose you are correctly calling your function displayOutput() in the onCreate() or any event for this change to show.
The answers here suggest that you must call your setText in onCreate. It's not true, you don't have to, you can do it elsewhere, the rule is that you do it after findViewById.
Your Main.java inflates activity_main layout, but the button that you have shown is in act_calculate.xml layout file. Therefore findViewById returns null, either move your button to activity_main or use the include to include it in your main layout.
You should set text in Content XML file instead of Navigation drawer.like this.
e.g:
View view = inflater.inflate(R.layout.fragment_home, container, false);
txtname = view.findViewById(R.id.usersession);
txtname.setText(name);
return view;
I have an issue creating a Button programmatically. The button is supposed to be inserted in a pre-existing layout.
And since I need the dimensions of a specific container I created a global layout listener for that container and in the onGlobalLayout callback i check for a valid size and then instantiate a new Button.
The context used is the context from the container.
final View container = activity.findViewById(...);
container.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (container.getWidth()>0 && container.getHeight()>0) {
Button button = new Button(container.getContext());
}
}
});
However, in rare cases - specifically when switching from one activity to another - the Button instanciation fails with a NullPointerException in the Android framework code.
java.lang.NullPointerException: Attempt to read from field 'android.animation.Animator android.animation.AnimatorSet$Node.mAnimation' on a null object reference
at android.animation.AnimatorSet.clone(AnimatorSet.java:725)
at android.animation.AnimatorSet.clone(AnimatorSet.java:682)
at android.animation.StateListAnimator.clone(StateListAnimator.java:148)
at android.animation.StateListAnimator$StateListAnimatorConstantState.newInstance(StateListAnimator.java:328)
at android.animation.StateListAnimator$StateListAnimatorConstantState.newInstance(StateListAnimator.java:327)
at android.content.res.ConstantState.newInstance(ConstantState.java:53)
at android.content.res.ConstantState.newInstance(ConstantState.java:61)
at android.content.res.ConfigurationBoundResourceCache.getInstance(ConfigurationBoundResourceCache.java:40)
at android.animation.AnimatorInflater.loadStateListAnimator(AnimatorInflater.java:163)
at android.view.View.<init>(View.java:4815)
at android.widget.TextView.<init>(TextView.java:995)
at android.widget.Button.<init>(Button.java:113)
at android.widget.Button.<init>(Button.java:106)
at android.widget.Button.<init>(Button.java:102)
at android.widget.Button.<init>(Button.java:98)
My assumption is that somehow the Context ist not valid any more but I can't put my finger on it..
I do remove the listener when the activity gets deactivated.
Any ideas?
As docs says OnGlobalLayoutListener
Interface definition for a callback to be invoked when the global layout state or the visibility of views within the view tree changes.
So when UI is destroing, you are getting "dying" View that causes NPE. You can try to unregister listener in onStop() to prevent that. Or if you need just to handle fully created View use
container.post(new Runnable() {
#Override
public void run() {
Button button = new Button(container.getContext());
}
});
The only solution I've found so far is to not create the button by calling
Button button = new Button(container.getContext());
but by creating a small layout xml file only containing the button and then instantiate the button like so:
LayoutInflater.from(context).inflate(R.layout.button, null)
I have a button with a method that is invoked upon clicking.
The method:
public void addToList(View view) {
System.out.println(1);
String str = "";
try{
str = edit.getText().toString();}
catch (Exception ex){
System.out.println( ex );
}
System.out.println(2);
new QueryInList( ).execute(helper, str);
System.out.println(3);
edit.setText(null);
System.out.println(4);
//adapter.notifyDataSetChanged();
}
Well, I always get the exception, it is a Nullpointerexception.
This quite baffles me, because edit IS initalized:
It is declared in the class:
private EditText edit;
and besides, it is initialized in onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
edit = (EditText)findViewById(R.id.textfield);
setContentView(R.layout.activity_view);
......}
So I wonder why I always get a Nullpointer?
Set the content view, before looking for the items. You dont have a view to find the items in until you set the content view.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
edit = (EditText)findViewById(R.id.textfield);
......}
Move edit = (EditText)findViewById(R.id.textfield); after your setContentView statement.
Here is a nice explanation from user #Squonk from another question:
setContentView(...) perfoms something called 'layout inflation'. What that means is it parses the XML in the relevant file (main.xml in your case) and creates instances of all the UI elements within it. It then attaches that view to the Activity. When you call findViewById(...) it doesn't reference your main.xml directly - instead it references the content view attached to the Activity, in other words the one inflated by setContentView(...)
I'm a beginner in Android and I'm testing my code using Android JUnit test.
So, I have a test activity that extends ActivityInstrumentationTestCase2<Activity>.
Activity has it's own layout in onCreate() method. (Main layout)
In my XML, I have a onClick attribute for a button that calls foo() method.
Back to Activity, in the foo(View v), I set my content view to a different layout.
I want to test that layout.
How do I get the layout though??
I know for the main layout, I can do this.
Activity act = getActivity();
View mainLayout = (View) act.findViewById(bla.bla.bla.R.id.main_layout);
How do I get the layout that I set in foo(View v)??
I've already tried doing,
fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);
and
act.setContentView(bla.bla.bla.R.layout.foo_layout);
fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);
I think I got NullPointerException for the first one and android.view.ViewRootImpl$CalledFromWrongThreadException
for the second one.
In your first try you get a NullPointerException because you are searching for your foo_layout wihtin your main_layout. findViewById is used to search for views wihtin a layout and not to find/inflate layouts. In your second try you get a CalledFromWrongThread Exception because you access the UI (setContentView()) from outside the UI thread. This is how you change the layout wihtin your test class:
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getActivity().setContentView(R.layout.foo_layout);
}
});
getInstrumentation().waitForIdleSync();
// now you can access your views from your foo_layout via getActivity().findViewById(...)
I don't know what you mean by "I want to test my layout". Either you want to check if your layout got successfully loaded through a button click or you want to access the views of the new (loaded) layout. In both cases you can do something like the following:
public void testLayout() {
// get your button that changes the layout of your activity.
// that button is in your main_layout
final Button btChangeLayout = (Button) getActivity().findViewById(R.id.yourButtonThatChangesTheLayout);
// perform a click in order to change the layout
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
btChangeLayout.performClick();
}
});
getInstrumentation().waitForIdleSync();
// get a reference of a view thats in your foo_layout e.g. a Button
Button aButtonInYourFooLayout = (Button) getActivity().findViewById(R.id.aButtonInYourFooLayout);
// now you can do what your want with your button/view.
//if you just want to know wheter your layout has successfully been loaded
//or not you can test your view if it's null
assertNotNull(aButtonInYourFooLayout);
}
i'm not sure ... but i think the first problem is:
act.setContentView(bla.bla.bla.R.id.foo_layout);
change to:
act.setContentView(bla.bla.bla.R.layout.foo_layout);
because in res/layout/ you have your UI, isn't it?
I'm using a child class which extends from main to setup some buttons. I am able to change variables created in main, such as TotalMoney from within child.
The problem is findViewById is giving a nullpointer exception. The code within buildthem() works fine when used in the main class.
I am using setContentView(R.layout.main); from within OnCreate in main. The Child class is instantiated and called from OnResume in main class.
Do I need to setContentView in the child aswell, or pass the content view from the main class somehow?
package com.chewyapps.markettrader;
class child extends main {
void buildthem(){
TotalMoney = TotalMoney + 9999;
Button MenuButton = (Button) findViewById(R.id.Menu);
//etc
}
}
I can't findViewById in Oncreate because the full code will use
for(i=0; i<buttonIDs.length; i++) {
Button b = (Button) findViewById(buttonIDs[i]);
//do other stuff
}
The for loop is needed for other things relating to each button. If I can get the basic example working though I assume the full code will work.
It hadn't occured to me before to mention this, but the child class is in a seperate file called child.java, from my main.java file in onResume I use:
child childObject = new child ();
childObject.buildthem();
Why not put this line:
Button MenuButton = (Button) findViewById(R.id.Menu);
in onCreate(), then you can either pass MenuButton into buildthem() as a parameter or reference it directly, depending on your design.
Please note that Java convention is to have variable names start with a lowercase letter, so menuButton not MenuButton.
EDIT
Then why not create an array of Buttons in onCreate() that you can later iterate through?
Button myButtons[] = new Button[buttonIDs.length];
for(int i=0; i<buttonIDs.length; i++) {
myButtons[i] = (Button) findViewById(buttonIDs[i]);
}
Then just iterate over the myButtons array in your child class.
What about:
Button MenuButton = (Button) this.findViewById(R.id.Menu);
or
Button MenuButton = (Button) Child.this.findViewById(R.id.Menu);