16

我创建了一个自定义对话框和一个布局 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'。在布局 xml 中设置 onClick 处理程序适用于活动,但不适用于对话框。有任何想法吗?我做错了什么?

4

9 回答 9

25

在Activity中定义方法(dialogClicked)。并修改 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); 
 }
}

我认为它有效:)

于 2010-12-01T04:03:28.347 回答
6

我认为这个问题是范围之一。我不确定你是如何在 xml 中解决这个问题的,但基本上你的布局 xml 中的 dialogClicked 方法不知道在哪里可以找到你在对话框类中定义的方法。

我见过的在自定义布局中绑定按钮的标准方法如下。

  1. 实现 OnClickListener 类
  2. 将按钮单击事件绑定到对话框类
  3. 根据id切换onClick按钮中的按钮。您需要为您的按钮添加一个 ID。

.

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 中的附加参数?别的东西。

于 2010-11-29T14:08:44.873 回答
2

我在 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 实例并将其设置为上下文。这个实例既不是自定义对话框类,也不是调用Activity,可以作为实现handler方法的地方。因此视图无法找到 onclick 处理程序方法。

但我必须使用 onclick XML 属性。有什么可用的解决方法吗?

于 2010-11-22T11:11:28.823 回答
1

对话框需要签名

dialogClicked(DialogInterface dialog, int id) { ... }
于 2010-11-22T08:56:35.857 回答
1

android:onClick="method"很酷,但它不适用于 Android 1.5,所以我暂时避免使用它。

一个简单的解决方法:

做你DialogActivity,用android:theme="@android:style/Theme.Dialog"在你身上AndroidManifest

于 2010-11-30T03:32:16.460 回答
1

继 Jett Hsieh 的帖子之后,我使用 showDialog 和 dismissDialog 实现了我的对话框略有不同,但让 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>
于 2011-11-10T11:27:26.690 回答
0

尝试在活动中而不是在对话框中定义该方法(dialogClicked)。

它可能使用反射,因此如果您使用不同的活动,只需在每个可能显示该对话框的活动中编写该方法

于 2010-11-27T15:53:43.083 回答
0

对话框总是作为 Activity 的一部分创建和显示。根据 Android 参考资料:

如果您决定在 onCreateDialog() 方法之外创建一个对话框,
它不会附加到 Activity。但是,您可以
使用 setOwnerActivity(Activity) 将其附加到 Activity。

另外,您是否传递了 getApplicationContext(); 返回的对象?到TestDialog的构造函数?

于 2010-11-28T04:14:00.867 回答
0

系统在布局被膨胀的地方或在 xml 被设置为内容的活动类中查找方法。

于 2011-12-22T21:50:50.873 回答