Android 安卓:对话框中的编辑文本不';t拔出软键盘

Android 安卓:对话框中的编辑文本不';t拔出软键盘,android,dialog,android-edittext,android-softkeyboard,Android,Dialog,Android Edittext,Android Softkeyboard,所以我有一个常见的问题,就是对话框中的编辑文本在获得焦点时不显示。我已经看到了一些变通方法,比如in、and(以及更多),但是我从来没有看到过一个令人满意的解释来解释为什么会发生这种情况 我更愿意让android为EditText使用自己的默认行为,而不是构建自己的,但似乎每个人(在那些线程中)都接受了对话框中EditText的默认行为是只提供一个光标而不提供键盘。为什么会这样 作为记录,这些解决方法似乎都不适用于我——我能做的最近的一件事是强制在对话框下面显示一个键盘(使用InputMetho

所以我有一个常见的问题,就是对话框中的编辑文本在获得焦点时不显示。我已经看到了一些变通方法,比如in、and(以及更多),但是我从来没有看到过一个令人满意的解释来解释为什么会发生这种情况

我更愿意让android为EditText使用自己的默认行为,而不是构建自己的,但似乎每个人(在那些线程中)都接受了对话框中EditText的默认行为是只提供一个光标而不提供键盘。为什么会这样

作为记录,这些解决方法似乎都不适用于我——我能做的最近的一件事是强制在对话框下面显示一个键盘(使用InputMethodManager.toggleSoftKeyboard(*))。我的特定配置是API15,EditText显示在AlertDialog中ListView的页脚中。EditText android:focusable=“true”已设置,onFocusChangeListener正在接收焦点事件

编辑:

根据要求,下面是我正在处理的特定代码片段。我不想为整个布局费心,但在这个特定的应用程序中,按下对话框上的按钮(类似于)就会显示EditText。它包含在默认情况下可见性为“gone”的RelativeLayout中:

使用此配置,当我第一次输入EditText时,onFocusChangedListener将触发,并生成一个如下所示的日志:

Focus requested, has focus.
Focus requested, doesn't have focus.
Focus requested, has focus.
键盘会出现然后消失,可能是因为我切换了两次,但即使我确保它保持不动,它也会在对话框窗口后面(灰色区域),如果不关闭对话框,就无法访问它


也就是说,我想强调的是,尽管我可以让这项工作顺利进行,但我主要感兴趣的是找到一个简单的原因,为什么EditText一开始没有触发,为什么这看起来如此普遍

我自己的应用程序也有同样的问题。如果您正在为API级别>=8进行开发,则可以使用以下代码段:

dialog.setOnShowListener(new OnShowListener() {
    @Override
     public void onShow(DialogInterface dialog) {
         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
         imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
    }
});
我还没有找到一个低API级别的解决方案


顺便说一句:这个代码段并不总是在emulator上工作。我不知道为什么。

好的,在读了很多之后,我明白了为什么这是一个问题,我不需要使用任何解决方法

问题似乎是(至少在我的情况下),因为您输入文本的位置最初是隐藏的(或嵌套的或其他),AlertDialog会自动设置标志WindowManager.LayoutParams.flag_ALT_FOCUSABLE_IM(或该标志与WindowManager.LayoutParams.flag_NOT FOCUSABLE的某种组合)这样事情就不会触发软输入来显示

我发现解决此问题的方法是在创建对话框后添加以下行:

dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

完成此操作后,EditText将像普通EditText一样工作,无需任何混乱或变通方法。

在对话框中显示键盘的完整代码:

public void onFocusChange(View v, boolean hasFocus) {
    Log.v("onFocusChange", hasFocus + " " + showkeyboard);
    if (hasFocus) {
        if (showkeyboard++ == 0) {
            alertDialog.getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
            alertDialog.getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        } else {
            showkeyboard = 1;
        }
    }
}

上面的代码非常有用。但是您必须在“create”方法之后调用“show”方法(我不知道为什么,但只有在我与ListView中的EditText的对话框中这样做)。 在方法onCreateDialog中:

@Override
protected Dialog onCreateDialog(int id) {
  switch (id) {
    case YOUR_DIALOG_ID: {
        //...
        AlertDialog a = new AlertDialog.Builder(this)./*
        ... set the properties here
        */
        .create();
        a.show(); //!!! this is very important to call the "show" method
        a.getWindow().clearFlags(
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        return a;
    }
  //...
  }
  return null;
}

谢谢大家!!我在警报对话框片段中嵌入的ListView的最后一行中嵌入了一个TextEdit。我使用您的解决方案清除标志作为后期运行,现在它可以完美地工作

    @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setTitle("My Title");
    m_adapter = new MyAdapter(getContext());
    builder.setAdapter(m_adapter, new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO Auto-generated method stub

        }
    }); 

    final AlertDialog dialog = builder.create();
    final ListView listView = dialog.getListView();
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

        }
    });

    listView.post(new Runnable() {

        @Override
        public void run() {
            dialog.getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);              
        }
    });
    return dialog;
}
@覆盖
创建对话框上的公共对话框(Bundle savedInstanceState){
AlertDialog.Builder=新建AlertDialog.Builder(getContext());
建造商名称(“我的名称”);
m_adapter=newmyadapter(getContext());
setAdapter(m_adapter,新的OnClickListener(){
@凌驾
public void onClick(DialogInterface dialog,int which){
//TODO自动生成的方法存根
}
}); 
最终AlertDialog=builder.create();
最终ListView ListView=dialog.getListView();
setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父级、视图、,
内部位置,长id){
}
});
post(新的Runnable(){
@凌驾
公开募捐{
dialog.getWindow().clearFlags(
WindowManager.LayoutParams.FLAG\u不可聚焦|
WindowManager.LayoutParams.FLAG\u ALT\u FOCUSABLE\u IM);
}
});
返回对话框;
}

如果您阅读了AlertDialog文档,您会发现:

AlertDialog类负责根据对话框中的任何视图是否从View.OnCheckKisTextEditor()返回true,为您自动设置*WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*。通常,您希望在没有文本编辑器的对话框中使用此设置,以便将其放置在当前输入法UI的顶部。您可以通过在调用onCreate后将标志强制设置为所需的模式来修改此行为

我遇到了您提到的ListView中的EditText对话框中的问题。我通过使用自己的FocusableListView覆盖自定义视图类(在我的示例中是ListView)修复了它,只覆盖了一个方法:

public class FocusableListView extends ListView {

    public FocusableListView(Context context) {
        super(context);
    }

    public FocusableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FocusableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onCheckIsTextEditor() {
        // this is where the magic happens
        return true;
    }
}
然后我在布局文件中使用它作为:

<?xml version="1.0" encoding="UTF-8"?>
<com.myexample.wiget.FocusableListView 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:descendantFocusability="beforeDescendants"
android:layout_height="wrap_content" />


在您的案例中,您可以用同样的方法覆盖RelativeLayout,它应该可以工作。

这里有一种方法:

    final Window dialogWindow = dialog.getWindow();
    dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
我想补充一下和

我自己有一个对话框,它是在
onCreateDialog()
方法中创建的,它(似乎)需要返回
dialog.show(),因此无法将layoutparams添加到创建对话框的对话框中。要解决此问题,只需保持
onCreateDialog()
方法不变,并添加一个
onResume()
方法,如下所示:

@Override
public void onResume() {
    super.onResume();
    Dialog dialog = getDialog();
    dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}

谢天谢地,这对我来说很有效。我在这个案子上已经有一段时间了。

这对我很有效。创建th
    final Window dialogWindow = dialog.getWindow();
    dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
This worked for me ----
editText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
//dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
InputMethodManager mgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(v, InputMethodManager.SHOW_FORCED);
editText.setFocusable(true);
}
});
@Override
public void onResume() {
    super.onResume();
    Dialog dialog = getDialog();
    dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
    AlertDialog dialog = builder.create();
    dialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    dialog.show();
    editText.requestFocus();