NullPointerException at Home.onCreate - android

I am trying to run a test program that allows a user to click a button and move to a different screen. I have the Home(First Activity) and Away(Second Activity) classes and a xml file specifying the layout for each. My source code is as follows:
public class Home extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button create = (Button)findViewById(R.id.create);
create.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
Intent intent = new Intent(Home.this, Away.class);
startActivity(intent);
}
});
setContentView(R.layout.main);
}
}
And Away.java
public class Away extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.away);
}
}
I get a NullPointerException in the DDMS trace
at Home.onCreate(line 17)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2627)
Anyone see anything in my code that may be causing this?

findViewById() traverses the view hierarchy set up when setContentView() inflates your layout. You cannot retrieve a reference to a view in your XML before you have called setContentView(). Change your onCreate() method in Home to look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Call me first
setContentView(R.layout.main);
Button create = (Button)findViewById(R.id.create);
create.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
Intent intent = new Intent(Home.this, Away.class);
startActivity(intent);
}
});
}
Otherwise, findViewById() will return null because there are no views in the tree...thus, a view with your requested id value doesn't exist.
Hope that helps!

If the findViewById call can't find the actual thing you are looking for, it could return a null object and cause the call to setOnClickListener to throw an NPE. Are you sure you've got the right ID (R.id.create) specified?

Related

Passing views between Activities

i've got a "simple" question:
How do i pass a view from an Activity to another?
In my case:
I've got a MainActivity with setContentView(R.layout.activity_main); In this activity_main i've declared a Relativelayout, whose Backgroundcolor I wanna change from another Activity, that gets its setContentView from an .xml file, where you cant find this RelativeLayout. How do i do that?
Thanks for the quick answer!
MainActivity.java
public class MainActivity extends AppCompatActivity{
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
//Save the text of the editText
bringer = savedInstanceState.getString("bringer");
input.setText(bringer);
//Save the Listview
content = savedInstanceState.getStringArrayList("content");
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, content);
layout = (ListView) findViewById(R.id.layout);
layout.setAdapter(adapter);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("content", content);
outState.putStringArrayList("list", list);
bringer = input.getText().toString();
outState.putString("bringer", bringer);
}
Second Activity:
public class pop extends Activity {
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Thats where it fails, because it couldnt get the parent-
view.
finish();
}
});
sure.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
}
The short answer is that you can't pass a View between activities.
If you have a View in ActivityOne that you want to modify based on the user's actions in ActivityTwo, then you should have ActivityOne launch ActivityTwo using startActivityForResult().
ActivityTwo can then call the setResult() method, and ActivityOne can implement onActivityResult() to receive that info.

How to get this from an anonymous method of abstract parent activity

I have an abstract Activity called Animal and two concrete descendant Activities Cat and Dog.
Cat & Dog are to present the same UI, consisting of a single button and so there is a single layout, activity_animal.xml that Animal sets as it's content view in OnCreate.
I want to set the button's OnClickListener in the abstract Animal class by means of an anonymous implementation of OnClickListener
private void setClickHandlers() {
((Button) findViewById(R.id.btn))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
//how to get a reference to this?
}
});
}
and in onClick I want to make a new Intent. To make the Intent I need a reference to this.
Normally, in anonymous method code like this, I could use syntax such as
EnclosingClass.this
but here, I don't know what the enclosing class will be. At run time, it could be either a Cat or a Dog.
How to do this?
The only way I can think of is to provide an abstract getThis() in Animal which is overridden in each concrete descendant.
You should be able to say Animal.this as your context.
private void setClickHandlers() {
View view = findViewById(R.id.btn);
view.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(Animal.this, MyDestinationActivity.class);
...
}
});
}
Animal.this will be either a Cat or Dog but since you only need Context the distinction is irrelevant.
public void onClick(View arg0) {
Activity host = (Activity) arg0.getContext();
}
I'd do it like:
private void setClickHandlers() {
final Animal thiz = this;
((Button) findViewById(R.id.btn))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent( thiz, AAAA.class );
}
});
}
You can determine the runtime type by using the instanceof operator.
if (Animal.this instanceof Dog) {
// dog related
}
else {
// cat related
}

Unable to start the Android application - NullPointerException on Click Listener

I'm having some problems trying to navigate between screens im my Android Project. I'm not creating other Activities classes yet, I'm just trying to open other XML files by the SetContentView(R.layout.XXX). Here is my main Activity:
package com.android.eduardo.navegacao;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class NavegacaoActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
chamaTelaPrincipal();
Button btCadastro = (Button) findViewById(R.id.btCadastro);
btCadastro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaCadastro();
}
});
Button btConsulta = (Button) findViewById(R.id.btConsulta);
btConsulta.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaConsulta();
}
});
Button btVoltar1 = (Button) findViewById(R.id.btVoltar);
btVoltar1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaTelaPrincipal();
}
});
}
public void chamaCadastro(){
setContentView(R.layout.activity_cadastro);
}
public void chamaConsulta(){
setContentView(R.layout.activity_consulta);
}
public void chamaTelaPrincipal(){
setContentView(R.layout.activity_navegacao);
}
}
As you can see, the "R.layout.activity_navegacao" is my main layout. When I try to execute this code the application closes and I receive a NullPointerException error, indicating some problems on SetContentView.
When I cut the code of the last setOnClickListener (the button "btVoltar") it works and I can open the two other screens. The button "btVoltar" is being used by the other XML to return to the main screen (activity_navegacao).
I already checked the id of the XML on the R class, and it's ok. I also don't receive any error notifications until I execute the project. Sorry for the bad english, if you guys can help me, I appreciate.
You are getting the NullPointerException because you are referencing a button that is on an XML layout which has not been displayed. (ie, the button is not found on activity_navegacao.xml).
For this reason, you should not call setContentView multiple times to change the view, like you are doing in this code. Instead, you should consider either making each screen a different activity (and calling setContentView only once per activity), or look into Fragments and FragmentTransactions. Fragments will allow you to replace the view, like you are attempting to do here.
You Can Initialize views only view is present in screen.In Your You clearly saying that the Button "btVoltar" not present in your current screen(activity_navegacao). So Initialize the view after its screen come to present.So Change your code like below
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
chamaTelaPrincipal();
Button btCadastro = (Button) findViewById(R.id.btCadastro);
btCadastro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaCadastro();
}
});
Button btConsulta = (Button) findViewById(R.id.btConsulta);
btConsulta.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaConsulta();
}
});
}
public void chamaCadastro(){
setContentView(R.layout.activity_cadastro);
}
public void chamaConsulta(){
setContentView(R.layout.activity_consulta);
}
public void chamaTelaPrincipal(){
setContentView(R.layout.activity_navegacao);
Button btVoltar1 = (Button) findViewById(R.id.btVoltar);
btVoltar1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chamaTelaPrincipal();
}
});
}
}

Open new activities OnImageButton click

I'm trying to create an activity with several buttons and I want that on click they open a new activity. I tried this code but it does not seem to work (I click the Puntos Image and nothing happens) Do you see what could be wrong?
public class MainMenu extends Activity implements OnClickListener{
ImageButton puntos;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu);
puntos = (ImageButton)findViewById(R.id.ImagePuntos);
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(arg0.getId() == R.id.ImagePuntos){
Intent openActivity1 = new Intent(MainMenu.this, MisPuntos.class);
startActivity(openActivity1);
}
}
}
In your xml layout, where you define ImagePuntos, give it the attribute
android:onClick="onClick"
Make sure that either the ImageButton has it's onClick attribute set to onClick in the XML or set it programmatically by adding puntos.setOnClickListener(this);

Why to inflate layout into another layout in Android?

I'm new in Android development and I wanted to make application that has header, body and footer and by clicking on one of the buttons in footer some layout will be loaded into body. I used some kind of "MasterPage" as described here.
When the button is pressed neither new_exercise layout nor exercises layout is loaded. Why? Maybe instead of all of this I should use any kind of tabs? Or maybe I can't inflate layout and should create new activity?
Here the code of the BaseActivity and NewExercise activity:
public class BaseActivity extends Activity{
LinearLayout linBaseBody;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.base_layout);
linBaseBody = (LinearLayout)findViewById(R.id.base_body);
initButtons();
}
#Override
public void setContentView(int id) {
LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(id, linBaseBody);
}
private void initButtons()
{
Button btn1 = (Button) findViewById(R.id.newEx);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setContentView(R.layout.new_exercise);
}
});
Button btn2 = (Button) findViewById(R.id.showAllEx);
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setContentView(R.layout.exercises);
}
});
}
public class NewExercise extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.new_exercise);
}
}
public class Exercises extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercises);
}
}
How your code is written, it would make more sense to use a new Activity. However, If you wanted to keep all of the view in one Activity, you could walk through all of your layouts calling mLayout.setVisible(View.VISIBLE); or you could use ViewStubs.
As to answer your question, why, what you are doing is adding the view (and their layouts) directly to your already created and inflated content view (the one you created in onCreate). You will need to clear the Activities contentView first to see the changes you are making with the button.

Categories

Resources