I'm trying to learn custom dialogs. I made one with a button in it and it comes up fine and I can hit breakpoints in the constructor and onCreate method, but when I click the button it crashes without ever getting to the button handler.
The dialog layout XML (my_dialog_layout.xml) is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/AButton"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="10px"
android:onClick="AButtonHandler"
android:text="Click Me"
/>
<TextView android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_toLeftOf="#id/AButton"
android:text="Click this button: "
/>
/>
... and the Dialog's java file is:
import android.os.Bundle;
import android.widget.Toast;
import android.view.View;
import android.content.Context;
import android.app.Dialog;
public class MyDialog extends Dialog {
public MyDialog(Context context) {
super(context);
setContentView(R.layout.my_dialog_layout);
}
public void AButtonHandler(View target) {
int i = 0; // just a placeholder to set a breakpoint at
i++; // " "
// Toast.makeText(this, "in AButtonHandler", Toast.LENGTH_LONG).show();
MyDialog.this.dismiss();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Toast.makeText(this, "Dialog onCreate", Toast.LENGTH_LONG).show();
}
}
When I click AButton it crashes in the debugger before getting to my breakpoint in AButtonHandler with "
Thread [<1> main] (Suspended (exception IllegalStateException))
View$1.onClick(View) line: 2059
Button(View).performClick() line: 2408
..."
Also notice the commented-out Toast's. I wanted to put Toasts in but thye compiler gives me: The method makeText(Context, CharSequence, int) in the type Toast is not applicable for the arguments (MyDialog,
String, int) What am I doing wrong?
Thanks in advance!
Second problem: A Dialog is not a Context. It has a Context. Use Toast.makeText(getContext(), ...).
First problem: Same thing. The method needs to be in the activity, not the dialog. (I should mention that I never tried onClick in a dialog. You may need to use a traditional OnClickListener.)
Side note: Function names should start with lower case.
After doing some more searching I discovered this:
Using onClick attribute in layout xml causes a NoSuchMethodException in Android dialogs
...exactly the same symptoms as I had! ... so apparently what I'm trying to do won't work. It's too bad - android:onClick - is very convenient.
I'll give eBoMike the answer credit on this because he straightened me out on the Toast and he at least alluded to the possibility that android:onClick was questionable.
Related
eveything looks to be fine, but I still get error when I try to change the view by pressing the button.
Here is code:
package com.example.testy;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ViewFlipper;
public class MainActivity extends Activity {
ViewFlipper flipper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flipper = (ViewFlipper) findViewById(R.id.viewFlipper1);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void clcik(View v) {
flipper.showNext();
}
}
And here is my XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top" >
<ViewFlipper
android:id="#+id/viewFlipper1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="Button!!" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView!!" />
</ViewFlipper>
</RelativeLayout>
Anyone knows what can be wrong in this code?
Thank you for answers!
Perhaps you should fix the name of your method to click ?
public void **clcik**(View v) {
flipper.showNext();
}
Due the wrong spell (clcik) in our activity code, you may be getting a Exception because Android can't find the click method.
And thanks to #yugidroid's answer I spot one more error on your code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flipper = (ViewFlipper) findViewById(R.id.viewFlipper1);
setContentView(R.layout.activity_main);
}
You call findViewById before even you have any Views (a call to setContentView) . You will get a NullPointException because of that.
I would recommend you to make a call to super.onCreate the very first line of your onCreate() method. That is what Google does.
Regarding setting the click listener on layout or creating a listener and setting on the code. Well, there is not much difference, although the latter is certainly faster as the first uses reflection, what has a higher cost than just calling a method.
First of all, make sure you call setContentView(R.layout.activity_main); after the super, its a good practice.
Your problem is that you set android:onClick="click" but you are refering the wrong method in Java (clcik doesn't exists).
I advice you to declare and set listeners in the activity, not in the xml.
This is my layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id = "#+id/postQues"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Post A Question" />
<TextView
android:id="#+id/postAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:text="Post Your Answer" />
<Button
android:id="#+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:clickable="true"
android:text="Submit" />
</RelativeLayout>
This is my activity:
package com.qstack.quizbox;
import roboguice.activity.RoboActivity;
import roboguice.inject.ContentView;
import roboguice.inject.InjectView;
import android.content.DialogInterface;
import android.view.View.OnClickListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.app.main.R;
#ContentView(R.layout.q_box)
public class QuizBox extends RoboActivity {
#InjectView(R.id.postQues) TextView postQues;
#InjectView(R.id.postAnswer) EditText postAnswer;
//#InjectView(R.id.submit) Button submitA;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
PostQuestion postQuestion = new PostQuestion();
postQues.setText(postQuestion.postQuestion());
submitA.setOnClickListener(submitAnswerListener);
}
private OnClickListener submitAnswerListener = new OnClickListener() {
//onClick view
public void onClick(View v) {
String answer;
answer = postA.getText().toString();
CheckAnswer checkAnswer = new CheckAnswer();
if (answer == checkAnswer.checkAnswer()) {
postA.setText("Correct");
}
}
};
}
I am getting a null pointer exception at line number 48, caused because postQues = null. When I remove postAnswer from the code, there is no null pointer exception. I've cleaned my project and all that. Any help
I can't comment yet on your answers, but people miss the point: he, like me, is using RoboGuice to inject views and stuff.
The sole purpouse of this framework is to avoid the boiler-plate part on onCreate() where you won't need to use setContentView and findViewById() anymore !
As to why he gets a NullePointerException, I don't know. I happen to have the same issue on one of my activies although it works just fine on all the other...
[EDIT]
I found the solution : I mixed up the type of two views.
If you put setContentView() where it is supposed to be, you will get the error.
The application wil say it cannot assign. Because the type doesn't match.
Therefore you get a nice
java.lang.RuntimeException: Unable to start activity ComponentInfo
But if you use RoboGuice framework, you get such error (well in my case I did not). However, all you views will all be null.
Hope it will help someone someday.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.yourxml); // you have missed this.....
PostQuestion postQuestion = new PostQuestion();
postQues.setText(postQuestion.postQuestion());
submitA.setOnClickListener(submitAnswerListener);
}
I had the same issue, and followed Mackovich's suggestions. He's right in pointing out that you don't need setContentView() with RoboGuice, as long as you annotate your activity with #ContentView.
In my case, the issue was caused by the fact that I had replaced an AutoCompleteTextView with an EditText, but forgot to make the same replacement in the activity with corresponding #InjectView. This was causing my NullPointerException.
Again, like Mackovich said, if I use setContentView() instead of #ContentView, the stacktrace gives me a more useful message:
Caused by: java.lang.IllegalArgumentException: Can't assign class android.support.v7.internal.widget.TintEditText value android.support.v7.internal.widget.TintEditText#426ce048 to class android.widget.AutoCompleteTextView field usernameTextView
I guess that's an argument against using Roboguice's #ContentView, at least until a fix is made in order to show the correct stacktrace.
You need to call setContentView(R.layout.the_xml) first (right after super.onCreate()). Otherwise RoboGuice doesn't know what to inject into your variables!
You forgot the following line in your code,
setContentView(R.layout.main);
which should be after this line of onCreate() method
super.onCreate(savedInstanceState);
you have missed that line
setContentView(R.layout.xml_filename);
I am doing the simplest of onClick models and cannot get the onClick method to fire. I know it is something simple, and I am new to Android. Any help is appreciated.
package com.bordeloniphone.timeentry;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class TimeEntryActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */
Button okButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
okButton = (Button) findViewById(R.id.btnOK);
okButton.setText(":)");
okButton.setOnClickListener(this);
//setContentView(okButton);
}
public void onClick(View v) {
Log.d("TEST", "TEST");
Toast.makeText(this, "TEST", Toast.LENGTH_SHORT).show();
}
}
Here is the main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnOK"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text="OK" />
</LinearLayout>
After much angst and gnashing of teeth, I figured it out. I had to delete the emulator device and add an new one and now it works like a champ. I appreciate everyone trying to help.
Instead of setting the onClicklistener to this, try this approach:
okButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.d("TEST", "TEST");
Toast.makeText(this, "TEST", Toast.LENGTH_SHORT).show();
}
});
You should try Cleaning your project or try to restart your Eclipse or any other Editor you are using as it is a valid code and should work fine.
UPDATE:
Also, you should check your Logcat, are you getting the output of Log.d("TEST", "TEST"); because your Toast seems to be implemented in a wrong manner.
Toast.makeText(this, "TEST", Toast.LENGTH_SHORT).show(); // wrong
Toast.makeText(Activity_name.this, "TEST", Toast.LENGTH_SHORT).show(); // correct
Using this in Toast inside the Listener means you are Referencing the Listener, which indeed should not be the case. You have to reference to the Activity itself so better use Activity_name.this.
Button iv_StyleInspiration_Back = (Button) findViewById(R.id.iv_StyleInspiration_Back);
iv_StyleInspiration_Back.setOnClickListener(this);
Try this Whenever you implement onclick in your activity you need to set as above to make it work for all controls and onclick should look something as below
#Override
public void onClick(View pView) {
if (null != pView) {
switch (pView.getId()) {
case R.id.iv_StyleInspiration_Back:
//do what you want
break;
default:
break;
}
}
}
Check for Three Steps:
find the button by id correctly
link the button to a listener. (adding the actionListener)
you specify a condition for this button in case of implementing an actionListener class.
try making the button clickable
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnOK"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text="OK"
android:clickable="true" />
How would one set the button1 variable to true in the ReadButtons method and have it be used in the onCreate method/class?
I am a noob and have spent many hours trying to figure this out. I have no idea where to look for the answer any further. I know I may be way off in my understanding of how this works. But I don't know how to correct that misunderstanding. My background is in C and other procedural programming languages. Thank you kindly for your help.
package com.test;
// This is being run on Eclipse Helios with ADK set to Android 2.2
// and a 10 inch landscape display tablet PC.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.Boolean;
public class ButtonTestActivity extends Activity {
public static Boolean button1 = false, button2 = false;
public static String myText="Drat";
TextView textV_Test_Display;
public void ReadButtons(){
Button btn_button1_Ref = (Button) findViewById(R.id.btn_button1);
btn_button1_Ref.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myText="YAY!";
button1 = true;
// if(button1) textV_Test_Display.setText(myText);
//
// When I uncomment the above, it works as I desire visually.
//
// How do I set button1=true here and have
// the value carry back to the onCreate class?
//
//
Toast.makeText(v.getContext(), "Button 1", Toast.LENGTH_SHORT)
.show();
}
});
Button btn_button2_Ref = (Button) findViewById(R.id.btn_button2);
btn_button2_Ref.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myText="WOOT!";
button2 = true;
// if(button2) textV_Test_Display.setText(myText);
//
// When I uncomment the above, it works as I desire visually.
//
// How do I set button2=true here and have
// the value carry back to the onCreate class?
//
//
Toast.makeText(v.getContext(), "Button 2", Toast.LENGTH_SHORT)
.show();
}
});
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textV_Test_Display = (TextView)findViewById(R.id.txtV_ID_Test_Data);
ReadButtons();
if(button1 || button2) textV_Test_Display.setText(myText);
// This does not display myText.
// I am not able to carry the button1 or button2 variables to
// this part of the program.
// textV_Test_Display.setText(myText);
// When uncommented, this displays the word "Drat".
// When commented out, the word "nope" is displayed.
// In the main.xml file the text is set to the word "nope"
// This tells me this command works as expected.
}
}
This is the main.xml file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#FF000FFF"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button android:id="#+id/btn_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:height="50dp"
android:text="Button 1"
android:width="140dp"
android:textSize="16dp"
android:layout_marginTop="160dp"
android:layout_marginLeft="220dp"></Button>
<Button android:id="#+id/btn_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:height="50dp"
android:text="Button 2"
android:width="140dp"
android:textSize="16dp"
android:layout_marginTop="160dp"
android:layout_marginLeft="450dp"></Button>
<TextView android:id="#+id/txtV_ID_Test_Data"
android:gravity="center"
android:textSize="28dp"
android:textStyle="bold"
android:typeface="sans"
android:textColor="#FFFFFFFF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="50dp"
android:height="50dp"
android:width="120dp"
android:text="nope"
android:layout_marginLeft="338dp"
android:background="#F00FF0F0"
></TextView>
</RelativeLayout>
Thanks
You are setting button1 = true in the onClick event. To be honest your code is pretty strange, I would take a look at some tutorials to see the correct way to do things in OO programming.
there is a couple of problems here.
You are setting the button to true in the listener, but that code will not be executed until the button is clicked.
you are trying to read the button1&button2 values in the on create method but so this code executes before the code in you listeners have exectued (because they haven't been clicked)
It look like you want to display some text based on weather either button is clicked: SO do this
make an update method
public void update() {
if(button1 || button2) textV_Test_Display.setText(myText);
}
called update() after you have set your variables in the button listener.
I'm trying to get a simple onClick to fire from an ImageButton - it seems like a simple enough task, but I'm obviously missing something here.
Here is my java file:
package com.jlbeard.android.testapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.Toast;
public class testapp extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//handle the button press
ImageButton mainButton = (ImageButton) findViewById(R.id.mainButton);
mainButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//show message
Toast.makeText(testapp.this, "Button Pressed", Toast.LENGTH_LONG);
}
});
}
}
Here is my layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:id="#+id/whereToEat"
android:src="#drawable/where_to_eat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8px"
/>
<ImageButton
android:id="#+id/mainButton"
android:src="#drawable/main_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#null"
android:clickable="true"
android:onClick="mainButtonClick"
/>
</RelativeLayout>
It seems to me that I'm missing something simple... but can't seem to figure it out. Thanks!
You didn't run show() method on Toast object. Very common mistake :-)
You also might have a problem due to the manifest setting onClick
android:onClick="mainButtonClick"
If mainButtonClick exists on post 1.5 devices it may be called instead, overriding the one you're setting in code
In my case, the imageButton was displayed behind a list. Because the list was empty, the ImageButton was seen but onClick was never fired.
Adding android:elevation="5dp" in the screen xml solve my problem
Note that if I use Button instead of ImageButton, elevation is not required.