Android TextView.SetText NullPointer Exception - android

I have two activities, activity one has buttons that refer to activity two and methods in it. I'm trying to use TextView.SetText to put something on the screen but keep getting NullPointerException.
Activity 2:
public class SomeActivity extends Activity {
TextView textview ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.some_activity);
textview = (TextView) findViewById( R.id.textview );
spill("Some text");
}
public void spill(String s){
textview.setText(s);
}
public void methodCalledFromActivityOne(){
System.out.println("Works");
spill("Why Doesn't this work?");
}
XML has this:
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
tools:context=".SomeActivity" />
I'm new to Android and will REALLY appreciate all/any help.
EDIT: The name of the XML is fine, the error only occurs when I press button 1 in activity 1 which calls methodCalledFromActivityOne().
This is what I get from LogCat:
Caused by: java.lang.NullPointerException at android.app.Activity.findViewById at data.storage.SomeActivity.spill at data.storage.SomeActivity.methodCalledFromActivityOne
at data.storage.ActivityOne.button1clicked

textview in activity 2 will be initialized only when onCreate() is called. And onCreate() of activity 2 will be called only when this activity comes into the phone view. You cannot set the values of views of another activity from your current activity. It is a bad idea.
If you want the values to get to activity 2, then send those in an intent.

If you're calling methodCalledFromActivityOne() method from another activity make sure you've created TextView property at that activity also. Otherwise it'll not work.

Related

Is it possible to bind onClick to specific activity?

I'm trying to build a single window app.
I have one layout (one xml file) and two activities. A button on the first activity starts the second activity, which is an infinite quiz. Then the second activity modifies some of the views (displays series of questions).
The button purpose is to finish the second activity if it's up, then start it again.
The problem is when I click the button the second time, the app crashes. Per my understanding, it's because it can't find the onClick method in the second activity code. This is the error message:
java.lang.IllegalStateException: Could not find method startQuiz(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'buttonStart'
I am looking for a way to bind the onClick of that button to only the main activity.
Is it possible? I Would appreciate any help.
My button xml:
<Button
android:id="#+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="32dp"
android:background="#android:color/holo_orange_dark"
android:onClick="startQuiz"
android:text="#string/start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/arithMul" />
My main activity:
/** Called when the user taps the Start button */
public void startQuiz(View view) {
finishActivity();
initQuiz();
}
public void initQuiz() {
Intent intent = new Intent(this, QuizActivity.class);
startActivity(intent);
}
public void finishActivity() {
Intent intent = new Intent("finish.quiz");
sendBroadcast(intent);
}
My second activity (QuizActivity):
public class QuizActivity extends AppCompatActivity {
TextView textQuestion = null;
EditText textAnswer = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// register to finish broadcast message
IntentFilter filter = new IntentFilter();
filter.addAction("finish.quiz");
registerReceiver(broadcast_reciever, filter);
// access main activity layout
setContentView(R.layout.activity_main);
// main layout text views
ConstraintLayout layoutChoose = findViewById(R.id.constraintLayoutQuiz);
layoutChoose.setVisibility(View.VISIBLE);
textQuestion = (TextView) findViewById(R.id.textViewQuestion);
textAnswer = (EditText) findViewById(R.id.editTextAnswer);
// start the quiz
startQuizSequence();
}
// register for broadcast to finish this activity
BroadcastReceiver broadcast_reciever = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent intent) {
//finish the activity
finish();
}
};
private void startQuizSequence() {
...
}
}
you could use findByViewId in both activities to find the button and explicitly set onClickListeners in each activity.
The problem is when I click the button the second time, the app crashes. Per my understanding, it's because it can't find the onClick method in the second activity code.
You're correct. When you're using Button with android:onClick attribute like the following:
<Button
android:id="#+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startQuiz"
...
/>
You're expected to create a method similar with the attribute value like this:
public void startQuiz(View v) {
}
You need to add the same method to another activity using the XML layout.
But, It becomes a problem when you're trying to rename the Button View and rename the android:onClick value to reflect the change. But then you forgot to rename the method in the Activity.
So, you need to decouple the layout from the code. Instead using a android:onClick attribute, you need to set the Button click listener. Update your Button view to something like this:
<!-- I usually use a more readable id for the button -->
<Button
android:id="#+id/start_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
/>
Then, set the click listener:
Button button = (Button) findViewById(R.id.start_btn);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do something here.
}
});

set text to TextView - NullPointerException [duplicate]

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;

android: App crashes when calling method in Main activity from custom activity

I'm trying to build a quiz-like app for guessing flags in android. Basically i have an activity named SetFlagActivity which receivs intent from the startFlagActivity(View v) in MainActivity if a button is clicked . It needs to do two things: # 1 if the user inputs correct name of the flag load a new flag and # 2 display message: "correct" else just display "wrong".
When the button is pressed the correct message is displayed, but the ImageView containing the image of the flag disappears. Also when the button is clicked again application crashes with following output:
I assumed that image doesn't appear because it's displayed in MainActivity, so i used finish() to go back. That fixed the app crashing, but again when i click the button nothing happens...no message is displayed. So the question is how do i use SetFlagActivity in a correct way that it displays my message and sets a new image..
Any help will be apreciated.
This gets the input and sends an intent
public void startFlagActivity(View v){
EditText flagInput = (EditText) findViewById(R.id.inputFlag);
String message = flagInput.getText().toString();
Intent intent = new Intent(MainActivity.this, SetFlagActivity.class);
if(!message.equals(""))
intent.putExtra("flag", message);
MainActivity.this.startActivity(intent);
}
And my SetFlagActivity looks like this:
package ivve.projects.flags;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class SetFlagActivity extends Activity {
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startFlagActivity(v);
}
});
TextView text = (TextView) findViewById(R.id.displayAnswer);
Intent intent = getIntent();
String value = intent.getStringExtra("flag");
if(value.equals("Iceland")){
text.setText("correct");
}
else{
text.setText("wrong");
}
finish();
}
}
Edit1: StartFlagActivity is actually not an activity by itself...it is a function inside the MainActivity
Edit2: I have added the onClick handler to my SetFlagActivity as suggested, but i get an error "The method startFlagActivity(View) is undefined for the type new View.OnClickListener(){}" which doesn't allow me to call to startFlagActivity method
You have declared the button (id = button) in activity_main.xml and set the button's OnClickListener through the onClick attribute to refer to the startFlagActivity method. What you are trying to do is to check if the TextView contains the correct answer and if yes, then proceed else remain in this page. One suggestion off topic would be to initialize the TextView variable within onCreate(). Here while it works for you, you are re-initializing it every time you click.
You have now inflated this view in MainActivity.
setContentView(R.layout.activity_main.xml); // This inflates the layout.
// Now you dynamically have set the flag. This is not part of the activity_main.xml
You have declared startFlagActivity() in MainActivity() and the logic behind it is that the new Activity should be started (when the button is clicked) with the answer passed in as a parameter to the intent. The newly started intent will check if the answer is correct and if yes, will display correct.
Now to answer your first question that the image view disappears. This happens because you have inflated activity_main.xml - but the ImageView was created dynamically in MainActivity and does not exist in SetFlagActivity (there basically is no image in this screen). This is why the map disappears but you see the rest of the layout as it remains the same.
Then, when you again click the button, the onClick() method (or in this case the startFlagActivity() method) does not exist for the activity SetFlagActivity currently being displayed and that was why you received the error log that said that the onClick() method startFlagActivity() does not exist for the SetFlagActivity screen. I hope this makes sense. Clicking the button now will not produce anything as there is no code to back it up (also produces error logs). I hope you see now where your logic is flawed.
You don't need to start a new activity. You can finish it off based on if-else conditions. Your algorithm would be:
If (answer = correct)
setImageView -> new drawable;
repeat process;
else
show wrong and repeat;
I hope this helps.
03-08 20:52:59.539: E/AndroidRuntime(9399): java.lang.IllegalStateException: Could not find a method startFlagActivity(View) in the activity class ivve.projects.flags.SetFlagActivity for onClick handler on view class android.widget.Button with id 'button'
03-08 20:52:59.539: E/AndroidRuntime(9399): at android.view.View$1.onClick(View.java:2131)
you forgot to declare startFlagActivity(View) inside SetFlagActivity. Maybe you have set the wrong layout in SetFlagActivity

TextView.setText (Android) is causing crashes.. any idea why?

Trying to get started with Android development, and doing some basic work with TextViews..
For some reason TextView's setText() method is causing huge problems for me.. here's a simplified version of my code to show what I mean:
package com.example.testapp;
import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
text.setText("literally anything");
}
}
This will cause a crash, and I don't understand why.. if I create the TextView within the onCreate it works just fine, but if I create it outside of it, it doesn't.. why is that? Has the line "TextView text;" not been executed yet or something?
Thanks!
You need to call setContentView() before initializing the TextView so that your Activity has access to all the layout components.
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text1);
text.setText("literally anything");
switch these 2 lines
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
you need to set the content first
From docs:
onCreate(Bundle) is where you initialize your activity. Most
importantly, here you will usually call setContentView(int) with a
layout resource defining your UI, and using findViewById(int) to
retrieve the widgets in that UI that you need to interact with
programmatically.
So this means that if you will reference your views in the layout, you must first set the content view and already then call findViewById method to reference child views of the layout resource defining your activity's UI
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
text.setText("literally anything");
If "literally anything" is a variable, which often may be the case, be sure that it isn't throwing a NullPointerException. I kept having that problem myself. I fixed it to be:
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
try {
text.setText("literally anything");
} catch (NullPointerException e) {
// Do something
}
Exceptions can be really useful, so if you're a beginning programmer, I suggest you put exception handling on your list of things to learn soon.

onClick attribute in XML linking to method in Activity class

There are quite a few questions about this subject, but could not find any with the specific problem I have...
In my layout.xml, I use the android:onClick tag for a Button to call the right onClickListener. I get the error :
java.lang.IllegalStateException: Could not find a method handle_cancel(View) in the activity class com.matthieu.HelloWorldApplication for onClick handler on view class android.widget.Button with id 'button_cancel'
I have that method implemented in the Activity, but it is looking for it in the class that extends Application... I don't understand why. The View and all that is setup only in the Activity.
If anyone needs, here is the declaration of that method (in my activity, NOT in HelloWorldApplication):
public void handle_cancel(View v) {
// do something useful here
}
Edit (from adamp request)... and probably answering my own question :
Here is part of the code where that layout is used...
public class AddVocabularyActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.top); // that layout contains an empty LinearLayout id/main_content
}
private some_other_function() {
LinearLayout main_content = (LinearLayout) findViewById(R.id.main_content);
main_content.removeAllViews();
View.inflate(getApplicationContext(), R.layout.hello, main_content); // layout.hello is the one containing the button
}
// some other stuff
}
While copy/paste this code, I am guessing the problem is that I used getApplicationContext to inflate the View with that Button...
As mentioned in my edit, changing the getApplicationContext() with the Activity context fixes it...
The convention works like this:
In the layout xml file, you give this attribute:
android:onClick:"methodname"
Then, inside a class, you define a method like this:
public void methodname(View v){
//your method code
}
Any other way of doing this is not documented. If you need parameters, just call another method inside that method.

Categories

Resources