Подтвердить что ты не робот

Использование атрибута onClick в макете xml вызывает NoSuchMethodException в диалоговом окне Android

Я создал пользовательский диалог и макет 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>

В классе диалога я реализовал метод "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");
 }

}

Когда я нажимаю кнопку, я получаю NoSuchMethodException 'dialogClicked'. Установка обработчика onClick в макете xml отлично подходит для действий, но не в диалогах. Есть идеи? Что я делаю неправильно?

4b9b3361

Ответ 1

Определите метод (dialogClicked) в Activity. И измените TestDialog как следующий код:

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); 
 }
}

Я думаю, что он работает:)

Ответ 2

Я думаю, что проблема является одной из областей. Я не уверен, как вы обращались к этому в xml, но по существу метод dialogClicked в вашем макете xml не знает, где найти метод, который вы определили в классе диалога.

Стандартный подход, который я видел для привязки кнопок в пользовательских макетах, выглядит следующим образом.

  • реализовать класс OnClickListener
  • Привязать кнопки click event к классу диалога
  • Выключите кнопки в кнопке onClick на основе идентификатора. Вам нужно добавить идентификатор к вашей кнопке.

.

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;
    }
}

}

Надеюсь, что это поможет. Было бы интересно узнать, было ли решение использовать xml onClick для привязки к методу. Возможно, дополнительный аргумент в setContentView? что-то другое.

Ответ 3

Я нашел следующий код в источнике View.java:

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

- > Представления используют его контекст для разрешения метода обработчика onclick.

Новейший код из источника Dialog.java:

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

В конструкторе диалога создается экземпляр ContextThemeWrapper и устанавливается как контекст. Этот экземпляр не является ни обычным диалоговым классом, ни вызывающей активностью, которая может быть местом для реализации метода обработчика. Поэтому представления не могут найти метод обработчика onclick.

Но я должен использовать атрибут onclick XML. Доступны ли какие-либо обходные пути?

Ответ 4

Диалоги нуждаются в сигнатуре

dialogClicked(DialogInterface dialog, int id) { ... }

Ответ 5

android:onClick="method" довольно круто, но он не работает на Android 1.5, поэтому я избегаю в течение некоторого времени.

Легкое обходное решение:

Сделайте Dialog a Activity и используйте android:theme="@android:style/Theme.Dialog" в AndroidManifest.

Ответ 6

Следуя сообщению Jett Hsieh, я немного изменил свои диалоги, используя showDialog и rejectDialog, но основные принципы работы android: onClick были одинаковыми, мой примерный код ниже для справок в будущем.

public class ExampleActivity extends Activity { 
    static final int DIALOG_DISCLAIMER = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        showDialog(DIALOG_DISCLAIMER);
    }

    protected Dialog onCreateDialog(int id)
    {
        Dialog dialog;
        switch(id)
        {
            case DIALOG_DISCLAIMER:
                dialog = new Dialog(this);
                dialog.setContentView(R.layout.main_disclaimer);

                LinearLayout ll = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.main_disclaimer, null);
                dialog.setContentView(ll);

                break;
            default:
                dialog = null;
        }       
        return dialog;
    }

    public void onClick(View v)
    {
        switch(v.getId())
        {
            case R.id.maindisclaimer_button_accept:
                dismissDialog(DIALOG_DISCLAIMER);
                break;
        }
    }
}

И файл макета:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:id="@+id/linearLayout1" 
              android:padding="10dp" 
              android:orientation="vertical"
              android:background="@drawable/roundedcorners">
    <Button
            android:id="@+id/maindisclaimer_button_accept"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/string_accept"
            android:onClick="onClick" >
        </Button>
</LinearLayout>

Ответ 7

Попробуйте определить этот метод (dialogClicked) в действии, а не в диалоговом окне.

Он может использовать отражение, поэтому, если вы используете разные действия, просто напишите этот метод в каждом действии, который может показать это диалоговое окно

Ответ 8

Диалоговое окно всегда создается и отображается как часть Activity. Согласно ссылкам на Android:

If you decide to create a dialog outside of the onCreateDialog() method, 
it will not be attached to an Activity. You can, however, 
attach it to an Activity with setOwnerActivity(Activity).

Также вы передаете объект, возвращенный getApplicationContext(); конструктору TestDialog?

Ответ 9

система ищет метод в том, где был раздуман макет, или в классе активности, для которого xml был установлен как контент.