Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using onClick attribute in layout xml causes a NoSuchMethodException in Android dialogs

I have created a custom dialog and a layout 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">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tap Me"
        android:onClick="dialogClicked" />
</LinearLayout>

In the dialog class I've implemented the method "dialogClicked(View v)":

public class TestDialog extends Dialog {

 public TestDialog(final Context context)
 {
  super(context);
 }

 @Override
 protected void onCreate(final Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.dialog);
 }

 public void dialogClicked(final View view)
 {
  System.out.println("clicked");
 }

}

When I tap the button I get a NoSuchMethodException 'dialogClicked'. Setting the onClick handler in layout xml works fine for activities, but not in dialogs. Any ideas? What I'm doing wrong?

like image 645
Impression Avatar asked Nov 22 '10 08:11

Impression


3 Answers

Define the method (dialogClicked) in Activity. And modify TestDialog like the following code:

public class TestDialog extends Dialog {
 Context mContext;
 public TestDialog(final Context context)
 {

  super(context);
  mContext=context;
 }

 @Override
 protected void onCreate(final Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  LinearLayout ll=(LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.dialog, null);
  setContentView(ll); 
 }
}

I think it works :)

like image 90
Jett Hsieh Avatar answered Oct 04 '22 05:10

Jett Hsieh


I think the issue is one of scope. I'm not sure how'd you address this in xml, but essentially the dialogueClicked method in your layout xml doesn't know where to find the method you've defined in the dialog class.

The standard approach i've seen to bind buttons in custom layouts is as follows.

  1. implement the OnClickListener class
  2. Bind the buttons click event to the dialog class
  3. Switch out the buttons in the onClick button based on id. You'd need to add an id to your button.

.

public class TestDialog extends Dialog implements android.view.View.OnClickListener
{
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog);
        ((Button)findViewById(R.id.dialog_btn_mybutton)).setOnClickListener(this);
    }



public void onClick(View view) 
{
    switch (view.getId())
    {
        case R.id.dialog_btn_mybutton:
            //do stuff
            // dismiss();
            // cancel etc.
        break;
    }
}

}

Hope that helps. Would still be interested in knowing if there was a solution to using xml onClick to bind to the method. Perhaps an additional argument in the setContentView? something r'other.

like image 41
Emile Avatar answered Oct 04 '22 06:10

Emile


I've found the following code in the View.java source:

public void onClick(View v) {
                            if (mHandler == null) {
                                try {
                                    mHandler = getContext().getClass().getMethod(handlerName,
                                            View.class);
    ...

-> The views uses its context to resolve the onclick handler method.

Noew the following code from Dialog.java source:

public Dialog(Context context, int theme) {
    mContext = new ContextThemeWrapper(context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
    ...

In the constructor of the dialog an instance of ContextThemeWrapper gets created and set as context. This instance is neither the custom dialog class, nor the calling activity, which can be the place for implementing the handler method. Therefore views are not able to find the onclick handler method.

But I have to use the onclick XML attribut. Any workarounds available?

like image 25
Impression Avatar answered Oct 04 '22 05:10

Impression