For button click listeners code runs fine when click listeners are defined in the activity but facing problem when defining click listener in the xml, no spelling mismatch
following error on logcat appears when listener are defined in xml, why?
java.lang.IllegalStateException: Could not find method addButtonClicked(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'addButton'
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"
android:id="#+id/addButton"
android:layout_marginTop="50dp"
android:onClick="addButtonClicked"
android:layout_below="#+id/inputField"
android:layout_alignLeft="#+id/inputField"
android:layout_alignStart="#+id/inputField" />
This is Activity Class
When click listener is defined in xml
public void addButtonClicked()
{
String text = inputField.getText().toString();
Products p = new Products(text);
dbObj.addProduct(p);
printDatabase();
}
When click listener is defined from Activity, This works fine
addButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
String text = inputField.getText().toString();
Products p = new Products(text);
dbObj.addProduct(p);
printDatabase();
}
});
Add this to you activity:
public void addButtonClicked(View view) {
//Your code here
}
Could not find method addButtonClicked(View)
addButtonClicked() method Missing .
Create addButtonClicked() method first .
public void addButtonClicked(View v)
{
// Add your Staff here
}
Clean-Rebuild-Run .
Related
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.
}
});
I've a recycle view adapter , I've implement addOnItemTouchListener to listen for each row and it works fine .
But I have two buttons in one of my rows and I've set on OnClickListener for them but it's not triggered . this is my code :
holder.register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ctx.startActivity(new Intent(ctx,Register.class));
}
});
I've set android clickable for my buttons but it didn't make any change :
<TextView
android:id="#+id/register"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:clickable="true"
android:textColor="#fff" />
How can I call on click listener for my buttons instead of recycle view TouchListener ?
First of all, as you said you have implemented TouchListener for each row. so your entire row listens to touch even, so another touch event in the same row gets affecting.
You need to override the onInterceptTouchEvent() for each child, otherwise, it will remain an onTouchEvent for the parent.
Better implement your onClick events in view holder itself. Use OnclickListener instead of TouchListener
Hope it helps :)
try below.
remove android:clickable from xml. and try setOnClickListener
<TextView
android:id="#+id/register"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:textColor="#fff" />
here is a snippet
// adaptor
public class youradaptor extends RecyclerView.Adapter<youradaptor.ViewHolder>
{
// create variable
OnItemClickListener mOnItemClickListener;
#Override
public void onBindViewHolder(Holder holder, int position)
{
holder.register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
mOnItemClickListener.click(position);
}
});
}
//interface for Click-listener
public interface OnItemClickListener
{
// method name which you can call in main class
void click(int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
mOnItemClickListener = onItemClickListener;
}
}
in the main class
youradaptorvarialble.setOnItemClickListener(new BrandProductGridAdapter.OnItemClickListener()
{
#Override
public void clcik(int position)
{
// write you action here
// enter code here
}
});
try this way and remove click event android:clickable="true" from xml file and add below code inside bindview holder
holder.detailimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ctx, MainActivity.class);
ctx.startActivity(intent);
}
});
MainActivity shows a viewpager
so there are 3 layout files:activity_main.xml、card1.xml and card2.xml
Now I want to get view from card1.xml and set the listener.
what should I do?
I tried using this:
LayoutInflater layout=this.getLayoutInflater();
View view=layout.inflate(R.layout.card1, null);
Button b=(Button)view.findViewById(R.id.b);
then set OnClickListener:
b.setOnClickListener(new MyClickListener(0));
but useless.
In your card1.xml, you can add a onClick attribute, and just provide the method name as the attribute's value, like this:
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="myMethod" />
Now in you MainActivity.java file, create a public method with return type as void, and which takes in a View parameter, like this:
public void myMethod(View v) {
// do your thing here
}
You can read more about it here.
public class MyClickListener implements OnClickListener {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.your_btn_id:
// your code
break;
}
}
}
another way is you can add button click listener in your card1.xml fragment class.
I am implementing common header in all activity.I want to implement click event for header.can anybody tell how to implement click event in BaseActivity(Parent Activity) in android.I am getting reference in parent activity .Is it possible to implement click using setOnClickListener in parent activity?
txtHeading =(TextView)findViewById(R.id.txtHeading);
I want to implement click event for textview in parent activity
Any help would be highly appreciated
I usually create some helper method on the parent activity
public void setHeaderOnClick(View.onClickListener clickListener){
txtHeading =(TextView)findViewById(R.id.txtHeading);
txtHeading.setOnClickListener(clickListener);
}
when on the fragment, you can use
((YourActivityName)getActivity()).setHeaderOnClick(new View.OnClickListener() {
#Override
public void onClick(View v) {
//method here
}
});
hope it helps
yes you can do it like...
1.)in your header a xml in the textView set these properties.
android:clickable="true"
android:onClick="onClick"
2.) write the direct public void onClick() in your BaseActivity Like
public void onClick(View v){
if(v.getId() == R.id.txtHeading){
}
}
it will working charm yes after doing these steps don't find your text view component in BaseActivity.
So I've been looking around for android tutorials, help questions, etc.. I keep running into questions or tutorials hard for me to understand.
Here's my questions:
When I create an item in the visual designer, piece of code will be created in the .xml.
How can I get the ID of that item to use it in the .java file later?
How can I add callbacks when let's say a button gets clicked?
Here's what I have so far:
.java
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void Button_click_callback() // Where to add the callback in the .xml?
{
// How to get button ID and change the text of it?
//Knowing this will help me A LOT!
}
}
.xml
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="79dp"
android:layout_marginTop="32dp"
android:text="Button" />
When I create an item in the visual designer, piece of code will be created in the .xml. How can I get the ID of that item to use it in the .java file later?
Step #1: Ensure that you have assigned an ID for the widget in the designer (in your XML above, you will see this as android:id="#+id/button1)
Step #2: In Java, you can get at the Java object for that widget by calling findViewById(R.id.button1) at some appropriate time (e.g., from an Activity, sometime after you call setContentView()).
How can I add callbacks when let's say a button gets clicked?
Generally, there is a setter method for this, such as setOnClickListener() that you can call on the Button you retrieved by findViewById().
In the specific case of click events on widgets hosted by activities, there is also an android:onClick attribute you can have in the XML, which supplies the name of a method on your Activity that will get called when the widget is clicked, instead of your having to use the setter.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do something in response to button click
}
});
}
All of this is extensively documented on the Android Developer site. You should be looking their for this basic stuff.
http://developer.android.com/guide/topics/ui/controls/button.html
You can use findViewById to get view ids from XML in Java, Make sure that you should declare the ids in views, otherwise it might cause exception which results apps force close
If you want call back with xml rather than programatically
you can declare android:onClick attribute on that Views in layout XML
For example, in your case you need add android:onClick="Button_click_callback" in your
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="79dp"
android:layout_marginTop="32dp"
android:text="Button"
android:onClick="Button_click_callback"/>
then you can use Button_click_callback method for call back in your Activity
public void Button_click_callback()
{
}
if you want call back programatically with java,
first you have get the view with findViewById and then you can add click listener to that view
You need to use the onClickListener and override the onClick method.
btn.setOnClickListener.(new View.OnClickListener(){
#Override
public void onClick(View v) {
//TO DO
}
});
OnClickListener is an interface. And thats why you need to override the OnClick method.
//in oncreate method of activity
//take button id like that
Button button1 = (Button)findViewById(R.id.button1);
//then implement on click listener for performing action on button
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do something in response to button click
}
});
}
//you can also implements onclicklistener in activity.its interface;
public class MainActivity extends Activity implements View.OnClickListener
//then generate method
public void onClick(View view) {
}
public class MainActivity extends Activity {
private Button button1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = findViewById(R.id.button1);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void Button_click_callback() {
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do something in response to button click
Log.e("click", "-------------button click");
}
});
}
}
Those two code snippets are equal, just implemented in two different ways.
Code Implementation
Button btn = (Button) findViewById(R.id.mybutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myFancyMethod(v);
}
});
// some more code
public void myFancyMethod(View v) {
// does something very interesting
}
Above is a code implementation of an OnClickListener. And this is the XML implementation.
XML Implementation
<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="myFancyMethod" />
1) First Look at your XML file.In code it shows
android:id="#+id/button1.
You can edit it on your own name.Same thing you can do to change it though the GUI appear at right side of your design.
You can get your ID using findViewById(R.id.your id name); function.
For an Example:
My button id is btn1.In my code I can use that button by getting it's Id as follows:
Button btn1=findViewById(R.id.btn1);
2)You can callback after creating your Button which you have created Before as follows;
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Create your code
}
});
}
For the call backs - The android component needs to be registered in the calling device . The id of the components has to be unique in the xmls.
Using the unique id the components can be dynamically altered or the call backs can be used.