在使用 XML onClick 时,Android 对话框出现 NoSuchMethodException 错误

3

我是一名Java和Android的新手,正在开发我的第一个测试应用程序。

虽然我的应用程序已经有了进展,但是我在使用对话框方面遇到了一些问题。

我是通过以下方式从Activity中显示对话框:

//BuyActivity.java
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shop);

    initialize_PR();
    display_PR();
    BuyDialog=new Dialog(this);
    BuyDialog.setContentView(R.layout.dialog_buy);

}
public void Action_ShowDialog_Buy(View view) {
    BuyDialog.show() ;
}

当触发 Action_ShowDialog_Buy 的Activity的按钮被点击时,对话框会正确地显示。但是在此之后,对话框本身具有一个按钮:

<!-- dialog_buy.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" >

<!-- Other stuff -->

<Button
    android:id="@+id/Button_Buy"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/Some_Other_Stuff"
    android:layout_centerHorizontal="true"
    android:text="@string/button_buy"
    android:onClick="Action_ShowDialog_Buy" />

</RelativeLayout>

在Activity上实现了按钮方法Action_ShowDialog_Buy:

public void Action_ShowDialog_Buy(View view) {
    BuyDialog.dismiss() ;
}

但是当我在对话框中单击按钮时,我会收到以下错误:
java.lang.IllegalStateException: Could not find a method BuyActivity.Action_ShowDialog_Buy(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button with id 'Button_Buy'

and below:

Caused by: java.lang.NoSuchMethodException:BuyActivity.Action_ShowDialog_Buy

但正如您在上面看到的,该方法存在于Activity中。
我认为我理解了这是某种作用域问题,但我没有理解它。请注意,我已经阅读了在Android对话框中使用布局xml中的onClick属性会导致NoSuchMethodException,但我需要理解,而不仅仅是复制代码。
非常感谢

你的Activity有两个相同的方法吗?一个是用于显示的public void Action_ShowDialog_Buy(View view),另一个是用于隐藏的吗? - Pasha
@Pasha 不,只想显示一个。我想使用 Dialog.dismiss 隐藏它。 - Envite
但是你写了这个:按钮方法Action_ShowDialog_Buy在Activity上实现:public void Action_ShowDialog_Buy(View view) { BuyDialog.dismiss() ; } 和这个//BuyActivity.java public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop);initialize_PR(); display_PR(); BuyDialog=new Dialog(this); BuyDialog.setContentView(R.layout.dialog_buy);} public void Action_ShowDialog_Buy(View view) { BuyDialog.show() ; } - Pasha
我不明白hide方法在哪里。 - Pasha
没有隐藏方法。我只是调用dialog.dismiss来隐藏它。 - Envite
5个回答

2
您正在尝试调用方法“Action_ShowDialog_Buy”,但是该方法在对话框对象中不存在!如果您在xml中指定了该方法,则不应该将该方法放在Activity中。如果您想在Activity中处理单击事件,应该以编程方式设置onClickListner:
Button b=(Button)BuyDialog.findViewById(R.id.Button_Buy);
b.setOnClickListener(new OnClickListener(){
    @Override
    onClick(View v){
      BuyDialog.dismiss();
    }

});

谢谢,我会尝试……但是为什么错误提示说在Activity中找不到这个方法呢? java.lang.NoSuchMethodException:BuyActivity.ActionShowDialog_Buy - Envite
我没有答案 :P - Sebastian Breit
@Envite请阅读完整的错误信息,它还说:“在活动类android.view.ContextThemeWrapper中”。 - Simon Forsberg
感谢@SimonAndréForsberg。我并不完全理解那个。 - Envite
@Perroloco: 这段代码不能编译通过:Eclipse显示: The Method setOnClickListener is not applicable(View.OnClickListener) in the type View is not applicable for the arguments (new onClickListener(){}) - Envite
那我不明白我的代码是怎么工作的...看一下: http://pastebin.com/H2HR8EP9 - Sebastian Breit

1

并且以下:

Caused by: java.lang.NoSuchMethodException:BuyActivity.ActionShowDialog_Buy

看这个 ActionShowDialog_Buy,你忘记在方法名中加下划线 _ 了。

抱歉,这是一个复制错误。在实际代码中名称是正确的。已经进行了修正。 - Envite

1
你需要在xml文件中使用set clickable true。
<!-- dialog_buy.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" >

    <!-- Other stuff -->

        <Button
            android:id="@+id/Button_Buy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/Some_Other_Stuff"
            android:layout_centerHorizontal="true"
            android:text="@string/button_buy"
            android:onClick="Action_ShowDialog_Buy"
            android:clickable="true" />

        </RelativeLayout>

1
+1 因为我想不出为什么会有人踩这个。 (评论,有人吗?) - user1499731

0

感谢所有尝试帮助的人。

我已经通过创建一个派生自Dialog的类并使用它来解决了这个问题,使用以下代码:

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;

public class BuyDialogClass extends Dialog
{

//Ensure this Dialog has a Context we can use
Context mContext ;

public BuyDialogClass(Context context) {
    super(context);
    mContext=context; //Store the Context as provided from caller
}

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

}

这使我能够像这样调用对话框:
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shop);

    initialize_PR();
    display_PR();
    BuyDialog=new BuyDialogClass(this);
    //The setContentView is not necessary here as we call it on the onCreate

    //We can NOT access Dialog widgets from here,
    //because the dialog has not yet been shown.

}
public void Action_ShowDialog_Buy(View view) {
    BuyDialog.show() ;

    //NOW, after showing the dialog, we can access its widgets
    jobject_SeekBar_buy= (SeekBar) BuyDialog.findViewById(R.id.SeekBar_Dialog_Buy) ;
    jobject_SeekBar_buy.setMax(PR_num_coins/currentPR_buy_price) ;
    jobject_SeekBar_buy.setOnSeekBarChangeListener(this);

}
public void Action_Buy_PR(View view) {
    BuyDialog.dismiss() ;
}

我通过阅读在Android对话框中使用onClick属性会导致NoSuchMethodException来完成了这个问题,但我仍然不理解这个Context问题。


0

Dialog使用ContextThemeWrapper

现在,我们得到的异常是...

java.lang.IllegalStateException: Could not find a method android:onClick="method" 
in the activity class android.view.ContextThemeWrapper
for onClick handler on view class android.widget.RadioButton with id 'statusSuspend'

要解决这个问题,只需使用适当的inflater即可

LayoutInflater.from(context)代替即可

  1. ((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE))

  2. getLayoutInflater()

避免使用void setContentView(int layoutResID),而是使用void setContentView(View view)。
并在Dialog构造函数中使用相同的context,即super(context)。
最后,请不要忘记在Activity中定义android:onClick="method",而不是在自定义类中定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接