Android 如何在 AlertDialog 中设置 Edittext

How to set Edittext in AlertDialog in Android

我有一个启动 Google 的 SpeechToText 对话框的 ImageButton。 此外,我正在为我的对话框使用自定义布局。

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp">

        <RelativeLayout
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <EditText
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:inputType="textMultiLine"
                android:ems="10"
                android:id="@+id/dialog_edittext"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:paddingRight="34dp" />

            <ImageButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/dialog_imagebutton"
                android:src="@drawable/ic_sirioriginalstate_teaser"
                android:background="@null"
                android:layout_alignRight="@+id/dialog_edittext"
                android:scaleType="fitEnd"
                android:paddingRight="5dp" />
        </RelativeLayout>

    </LinearLayout>
</RelativeLayout>

如您所见,我有一个 Imagebutton 和一个 Edittext,我必须在其中设置文本。

                LayoutInflater li = LayoutInflater.from(context);
                View view = li.inflate(R.layout.dialog, null);
                final EditText text = (EditText) view.findViewById(R.id.dialog_edittext);

                final ImageButton imageButton = (ImageButton) view.findViewById(R.id.dialog_imagebutton);
                imageButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        promtSpeechInput();
                    }
                });

                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setView(view);
                AlertDialog alertDialog = builder.create();
                alertDialog.show();
                return true;

promptSpeechInput 方法启动语音对话框。

    private void promtSpeechInput() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 6000);
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
            "Aufnahme...");

    try {
        startActivityForResult(intent, SPEECH_TO_TEXT_REQUEST);
    } catch (ActivityNotFoundException e) {
        Toast.makeText(getApplicationContext(), "Test01", Toast.LENGTH_SHORT).show();
    }
}

如果说出某些内容,将调用 onActivityResult 方法。 还有我的问题。

如何将口语设置到对话框中Edittext

我以前用过同样的方法,但这次没用。

if (resultCode == RESULT_OK && null != data) {
                ArrayList<String> result = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                textField.setText(textField.getText() + " " + result.get(0));
            }
            break;

我尝试自己做一些事情,但这行不通:

if (resultCode == RESULT_OK && null != data) {
            ArrayList<String> result = data
                    .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            LayoutInflater li = LayoutInflater.from(context);
            View view = li.inflate(R.layout.dialog, null);

            final EditText text = (EditText) view.findViewById(R.id.dialog_edittext);
            text.setText(text.getText().toString() + " " + result.get(0));
        }

所以你需要将调用的结果activity转发给对话框。由于接收结果的是调用 activity,因此调用 activity 必须将结果传递给对话框。通常这是通过监听器完成的。调用 activity 将具有某种类型的成员,例如

interface MyActivityListener {
    void onMyActivityResult(String s);
};
MyActivityListener currentListener;

理想情况下,您的对话框将实现此接口本身或拥有一个成员,

// inside the dialog class
MyActivityListener mListener = new MyActivityListener() {
    void onMyActivityResult(String s) {
        ...
    }
}

但是您不能向对话框中添加字段,因为您使用的是生成器。但是您可以将对话框包装在 class.

// in CallingActivity:
interface MyActivityListener {
    void onMyActivityResult(String s);
};
MyActivityListener currentListener;

void onActivityResult(...) {
        if (currentListener != null) {
              currentListener.onMyActivityResult(....);
        }
    }
}

class DialogWrapper { // contains members that the dialog cannot contain (because the builder always returns an AlertDialog)
    View rootView;
    MyActivityListener mListener = new MyActivityListener() {
       void onMyActivityResult(String s) {
           ((EditText)rootView.findViewById(R.id.myeditor)).setText(s);
           ...
       }
    }

    void showDialog() {
            AlertDialog.Builder builder = ...;
            ... li = ...;
            rootView = li.inflate(...);
            builder.setView(rootView);
            builder.setOnDismissListener(
               new ... { currentListener = null; }  // !!!!!
            );
            AlertDialog alertDialog = builder.create();
            currentListener = mListener;   // !!!!!
            alertDialog.show();
    }
}

// how to use:
void someMethod() {
    new DialogWrapper.showDialog();
}

或者,您也可以决定,尽管所有这些侦听器都非常符合标准,但归根结底是 activity 具有指向根视图的指针。所以如果你的 activity 真的很小,你可以声明一个

// in CallingActivity
View pointerToCurrentDialogRootView;

并在对话框的 OnDismissListener 中将其设置为 null。

这是一个好的解决方案吗?好吧,OOP 是职责分配,activity 不应该负责对对话框的 EditText 做任何事情。 OTOH,已经发生了 activity 收到对话要求的结果。我的建议是:将所有 activity-to-dialog 内容放在内部 class 中。也许,扩展 DialogWrapper(上面)来完成与对话框相关的所有事情,即使您决定删除侦听器内容。