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 のインスタンスが作成され、コンテキストとして設定されます。このインスタンスは、カスタム ダイアログ クラスでも、ハンドラー メソッドを実装する場所となる呼び出しアクティビティでもありません。したがって、ビューは onclick ハンドラー メソッドを見つけることができません。

しかし、onclick XML 属性を使用する必要があります。利用可能な回避策はありますか?

于 2010-11-22T11:11:28.823 に答える
1

android:onClick="method"はかなりクールですが、Android 1.5 では動作しないため、しばらく避けています。

簡単な回避策:

あなたDialogの anActivityを作成し、使用android:theme="@android:style/Theme.Dialog"しますAndroidManifest

于 2010-11-30T03:32:16.460 に答える
1

ダイアログには署名が必要です

dialogClicked(DialogInterface dialog, int id) { ... }
于 2010-11-22T08:56:35.857 に答える
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

ダイアログは、常にアクティビティの一部として作成および表示されます。Androidリファレンスによると:

onCreateDialog() メソッド以外でダイアログを作成する場合は、
アクティビティには添付されません。ただし、次のことができます。
setOwnerActivity(Activity) を使用してアクティビティにアタッチします。

また、 getApplicationContext(); によって返されたオブジェクトを渡していますか? TestDialog のコンストラクタに?

于 2010-11-28T04:14:00.867 に答える
0

システムは、レイアウトがインフレートされた場所、または xml がコンテンツとして設定されたアクティビティ クラスでメソッドを探します。

于 2011-12-22T21:50:50.873 に答える
0

ダイアログではなく、アクティビティでそのメソッド (dialogClicked) を定義してみてください。

リフレクションを使用する可能性があるため、異なるアクティビティを使用する場合は、そのダイアログを表示する可能性のある各アクティビティにそのメソッドを記述するだけです

于 2010-11-27T15:53:43.083 に答える