Android:等待用户input对话框?

我想实现一个方法,显示一个对话框,等到对话框被解散,然后根据对话框的内容返回一个结果。 这可能吗?

public String getUserInput() { //do something to show dialog String input = //get input from dialog return input; } 

我实际上是试图实现一个接口,它具有方法“公共stringgetUserInput()”,其中返回的string必须通过对话框检索。 这很容易在java中完成,在android中似乎不可能?

编辑:张贴一些示例代码作为评论请求

getInput()必须从后台线程调用(我从AsynchTask调用它)。 getInput()显示一个对话框并调用wait。 当在对话框中按下okbutton时,对话框将用户input设置在成员variables中并调用notify。 当notify被调用时,getInput()继续并返回成员variables。

 String m_Input; public synchronized String getInput() { runOnUiThread(new Runnable() { @Override public void run() { AlertDialog.Builder alert = new AlertDialog.Builder(context); //customize alert dialog to allow desired input alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { m_Input = alert.getCustomInput(); notify(); } }); alert.show(); } }); try { wait(); } catch (InterruptedException e) { } return m_Input; } 

这可能吗?

没有。在Android中没有阻塞的UI模型。 一切都是asynchronous的。

UPDATE

为了回应您对问题本身的一些评论,您不能从后台线程显示UI。 正如我在这个答案中写的,在Android中没有阻塞的UI模型。 只要把你的代码放到对话框的button处理程序中,你就可以在对话框被接受的时候执行它,比如在这个示例项目中 。

感谢所有的反馈,我能够使用后台线程和wait()和notify()来解决这个问题。 我认识到这不是给定模式的最大想法,但是需要遵守我正在合作的一个图书馆。

正确的做法是事件驱动的程序模式,即“不要打电话给我们,我们会打电话给你”。

在简单的控制台模式编程中,您的代码往往会调用阻塞input函数,直到获得值才会返回。

许多gui编程环境的工作方式不同 – 您的代码通常不会正常运行,而是在发生某些潜在的兴趣时由操作系统/窗口pipe理器调用。 你做了一些回应,并立即返回 – 如果你不这样做,你不能通知任何其他事情,因为操作系统无法联系你,直到你回来。 (与win32相比,好像消息循环是由Android实现的,你只需要编写消息循环调用事件的其余代码 – 如果不及时返回,消息循环会挂起)

因此,你需要重新思考你的程序stream程的概念。 不要把待办事项清单写成简单的一系列陈述,而应该把它看作是一系列相互依赖,相互依赖的行动。 记住你现在在状态variables中的动作。 当你用一个事件如用户input来调用时,看看这个事件是否意味着现在可以继续下一步了,如果是这样,更新你的状态variables,然后立即返回到操作系统,以便能够接收下一个事件。 如果事件不是你所需要的,那么只需返回而不更新你的状态。

如果这个模型不适合你,你可以做的是编写一个程序逻辑的后台线程,它使用阻塞input像控制台模式应用程序一样运行。 但是你的input函数实际上只是等待一个标志,或者被告知input是可用的。 然后,在您的UI线程Android交付事件,您更新标志,并立即返回。 后台线程看到标志已经改变,表示数据已经提供,并继续执行。 (就像一个androidterminal模拟器一样,这是一个极端,其中背景组件实际上是另一个进程 – 一个控制台模式linux的一个,它得到它的input使用潜在的阻塞来自pipe道的I / O.Java组件接受Android UI事件和将字符填充到stdinpipe道中,并将其拖出stdoutpipe道以显示在屏幕上。)

像这样的事情会做

 /** * */ import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.WindowManager; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; /** * @author */ public class TextEntryActivity extends Activity { private EditText et; /* * (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_entry); getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, WindowManager.LayoutParams.FLAG_BLUR_BEHIND); // title try { String s = getIntent().getExtras().getString("title"); if (s.length() > 0) { this.setTitle(s); } } catch (Exception e) { } // value try { et = ((EditText) findViewById(R.id.txtValue)); et.setText(getIntent().getExtras().getString("value")); } catch (Exception e) { } // button ((Button) findViewById(R.id.btnDone)).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { executeDone(); } }); } /* (non-Javadoc) * @see android.app.Activity#onBackPressed() */ @Override public void onBackPressed() { executeDone(); super.onBackPressed(); } /** * */ private void executeDone() { Intent resultIntent = new Intent(); resultIntent.putExtra("value", TextEntryActivity.this.et.getText().toString()); setResult(Activity.RESULT_OK, resultIntent); finish(); } } 

发射是:

 public void launchPreferedNameEdit() { Intent foo = new Intent(this, TextEntryActivity.class); foo.putExtra("value", objItem.getPreferedNickname()); this.startActivityForResult(foo, EDIT_PREFERED_NAME); } 

你通过使用得到结果

 protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case EDIT_PREFERED_NAME: try { String value = data.getStringExtra("value"); if (value != null && value.length() > 0) { } } catch (Exception e) { } break; default: break; } } 

CASE:我的数据已经准备好在首选项更改侦听器事件之后进行处理,我需要添加从用户查询的string。 当选项菜单打开时,popup警告对话框是不可能的,所以我不得不等待。 我把这个半完整的对象投入到工作stream中的下一个活动中,并设置它的onResume()来检查它的占位符是否为null,在这种情况下,我popup对话框并完成对象*“ 在对话框的button处理程序中 *

由于这是我的第一篇文章,我不能投票给上面给出的正确答案,但要保存任何人跑到这个不太正确的解决scheme的时间和优雅。 对话框就是这个地方。

你可以从状态机的angular度思考,如果你最初需要第一次用户input,你可以设置一个标记来标记“用户input需要”或其他什么。 然后在处理一个事件时,检查该标志,如果设置了,则启动一个对话框作为该事件的唯一动作并取消设置该标志。 然后,在处理用户input后,从对话框事件处理程序中,您可以调用通常用于不需要对话框的情况下的代码。