web-dev-qa-db-ja.com

AlertDialog.Builderオブジェクトが開かれるたびにソフトキーボードを表示する

入力ダイアログを開くための私のコードは次のとおりです。

final AlertDialog.Builder alert = new AlertDialog.Builder(this);  
alert.setTitle("Dialog Title");  
alert.setMessage("Request information");  
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.edittextautotextlayout, null);
final EditText inputBox = (EditText) textEntryView.findViewById(R.id.my_et_layout);
alert.setView(inputBox);

これは、ソフトキーボードが表示される前にテキスト入力行をタップする必要があることを除いて、正常に機能します。

与えられたアドバイスに従って ここ 私は挿入しようとしました:

inputBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            alert.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});

しかし、「メソッドgetWindow()がタイプAlertDialog.Builderに対して定義されていない」というEclipseオブジェクト。

SetOnFocusChangeListenerコードはAlertDialogオブジェクトに対しては機能するが、AlertDialog.Builderに対しては機能しないようです。ソフトキーボードが自動的に表示されるようにコードを変更するにはどうすればよいですか。

33
prepbgg

Mur Votema(上記の彼の回答を参照)の励ましで、Dialogクラスに基づいてカスタムダイアログを作成することで私の質問に答えました。 AlertDialog.Builderに基づくアラートとは異なり、このようなカスタムダイアログはgetWindow()。setSoftInputMode(...)コマンドを受け入れるため、ソフトキーボードを自動的に表示できます。

カスタムダイアログの作成に関するガイダンスとして、 this web page および this が特に役立ちました。

6
prepbgg

内部の特定のフォームウィジェットがフォーカスを取得するのではなく(ダイアログがEditTextとボタンのみを表示する場合など)、ダイアログが開いたらすぐにキーボードを常に表示する必要がある限り、次のようにすることができます以下:

_AlertDialog alertToShow = alert.create();
alertToShow.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
alertToShow.show();
_

ビルダーで.show()をすぐに呼び出すのではなく、代わりに.create()を呼び出して、画面に表示する前に追加の処理を行うことができます。

78
Defragged

これはミアネルへの反応です。

メニューオプションが選択されると、次のメソッドが呼び出されます。

private void addNote() {
    final Dialog dialog = new Dialog(this);
    dialog.setContentView(R.layout.textentryalertdialog);
    dialog.setTitle("Add note");
    TextView msgText = (TextView) dialog.findViewById(R.id.messagetext);
    msgText.setText("Whatever Prompt you want");
    final EditText inputLine = (EditText) dialog.findViewById(R.id.my_edittext);
    Button okButton = (Button) dialog.findViewById(R.id.OKButton);
    okButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
            // app specific code
        }           
    });
    Button cancelButton = (Button) dialog.findViewById(R.id.CancelButton);
    cancelButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
        }           
    });
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    dialog.show();
}

Textentryalertdialog.xmlファイルは、以下を含む線形レイアウトを定義します

TextView Android:id = "@ + id/messagetext" ...

EditText Android:id = "@ + id/my_edittext" ...

ボタンAndroid:id = "@ + id/OKButton" ...

ボタンAndroid:id = "@ + id/CancelButton" ...

これがお役に立てば幸いです。

15
prepbgg

ダイアログボックスをソフトキーパッドと共にポップアップして、ユーザーがダイアログ内の編集テキストをタップせずにキーパッドを表示できるようにする場合、たとえば、ダイアログボックスから値を取得する場合は、この単純なコードを使用します。それはあなたの問題を解決します。

        public void onClick(final View v) 
        {   
             AlertDialog.Builder alert = new AlertDialog.Builder(v.getContext());                 
              alert.setIcon(R.drawable.smsicon);
              alert.setTitle(" Secrete Code");  
              alert.setMessage("Enter a Key for secrete text !");
              final EditText shft_val = new EditText(v.getContext()); 
              shft_val.setInputType(InputType.TYPE_CLASS_NUMBER);//changing the keyBoard to No only,restrict the string etc
              alert.setView(shft_val);

     //pOp Up the key pad on Edit Text  focus event

             shft_val.setOnFocusChangeListener(new OnFocusChangeListener()
             {
                public void onFocusChange(View arg0, boolean arg1)
                {  InputMethodManager inputMgr = (InputMethodManager)v.getContext().
                                    getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
                        }
                    });

                 alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() 
                 {  
                 public void onClick(DialogInterface dialog, int whichButton) 
                 {
                    //Your specific code... 
                 }
                 });
                 alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                     public void onClick(DialogInterface dialog, int which) {                       
                         dialog.dismiss();
                         return;   
                     }
                 });
                       alert.show();
                    }
2
Pir Fahim Shah

EditText-> inputBox.requestFocus()などにフォーカスを設定しようとしましたか?

1
Tima

元の質問ではほとんど問題がなかったと思います。 getWindow()を呼び出す_final AlertDialog_を作成してみてください。

_// Create the dialog used to modify the mailbox alias
final AlertDialog dialog = alert.create();

inputBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            dialog.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});
_

私はこのコードをテストしましたが、次のようなほとんどのデバイスでキーボードが自動的に表示されるようになりました。

  • Samsung Galaxy Tab OS 2.2
  • Samsung Galaxy S OS 2.1
  • HTC Sensation OS 2.3.4

このソリューションに関するその他のコメント:

1)このコードが機能しなくなる可能性があるため、フォーカスを要求するためにXMLに何かがあるかどうかを確認します(リンク先の質問のTedによると)。

2)このコードは、OS 2.3.4を実行しているHTC G2では機能しないようです。これは物理キーボードがあり、おそらく_WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE_オプションが機能しないためでしょうか?

また、SOFT_INPUT_STATE_VISIBLE(ALWAYSなし)も試しましたが、キーボードが自動的に表示されなくなりました。

3)ユーザーがキーボードの[完了]ボタンを押して変更を送信できるように、コードを追加することもできます。

_inputAlias.setOnKeyListener(new OnKeyListener()
{
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent event)
  {
    if (keyCode == KeyEvent.KEYCODE_ENTER &&
        inputAlias.isFocused() &&
        inputAlias.getText().length() != 0)
    {
      // Save the new information here

  // Dismiss the dialog
      dialog.dismiss();
      return true;
    }
    return false;
  }
});
_
1
Dan J

inputBoxを使用してみてください

inputBox.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
1
Aaron Saunders

ビューを使用してみてください

v.getWindow().setSoftInputMode( 
           WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
1
pengwang

AlertDialogを作成し、EditTextを含むカスタムビューを使用します。また、ダイアログが表示されたときにソフトキーボードが表示され、ユーザーが[OK]ボタンをクリックしたかどうかに関係なく、ダイアログの外部に表示されないようにしたいと考えています。

このコードはandroidx.perference.PreferenceDialogFragmentCompatからのものであり、少し整理しています。

final AlertDialog.Builder builder = new AlertDialog.Builder(context)
        .setTitle(mDialogTitle)
        .setPositiveButton(mPositiveButtonText, null)
        .setNegativeButton(mNegativeButtonText, null);

View contentView = LayoutInflater.from(context).inflate(resId, null);

mEditText = contentView.findViewById(Android.R.id.edit);

/**
 * From PreferenceDialogFragmentCompat.needInputMethod
 * <p>Note: If your application targets P or above, ensure your subclass manually requests
 * focus (ideally in {@link #onBindDialogView(View)}) for the input field in order to
 * correctly attach the input method to the field.
 */
mEditText.requestFocus();

builder.setView(contentView);

final Dialog dialog = builder.create();
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

// This is not from PreferenceDialogFragmentCompat and I add it.
// It seems the soft keyboard won't get dismissed on some old devices without this line.
dialog.setOnDismissListener {
    dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

dialog.show();

マニフェストを変更する必要はありません。これは自動的にEditTextにフォーカスし、ダイアログのアクションボタンをクリックしたか、ダイアログの外のどこかをクリックしても閉じられます。

1
Dewey Reed

確かに、この質問は本当に古いですが、私は約20種類のいわゆる「ソリューション」を試したので、実際に機能したものだけを最終的に投稿します。

この回答は、私を正しい方向に向けたPir Fahim Shahの回答に基づいています(ありがとう)。

ダイアログを閉じたときに強制キーボードが非表示になるように、これをアクティビティのonCreateに入れてください。

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

次に、次のようなダイアログを作成します。

    AlertDialog.Builder builder = new Builder(this);
    builder.setTitle("title");
    final EditText input = new EditText(this);
    input.setText("text");
    input.setSelection(input.getText().length()); // set cursor to end
    builder.setView(input);
    input.setOnFocusChangeListener(new OnFocusChangeListener()  {
       public void onFocusChange(View v, boolean hasFocus) { 
           if(hasFocus) {
               InputMethodManager inputMgr = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
               inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
           }
       }
    });
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // do something here
            dialog.dismiss();
        }
    });
    builder.setNegativeButton("Cancel", null);
    builder.show();
1
sec_aw

次のコードスニペットでは、LinearLayoutで任意のDialogFragmentをホストする方法を示します。 AlertDialogを使用する方法(ソフトキーボードが機能しない場合)とAlertDialogを使用しない方法(ソフトキーボードが機能する場合):

public static LinearLayout createLinearLayout(Context context)
{
    LinearLayout linearLayout = new LinearLayout(context);
    linearLayout.setOrientation(LinearLayout.VERTICAL);
    linearLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    String html;
    html = "<form action=search method=get >\n";
    html += "Google Search: <input name=q value=\"Johnny Depp\" /><br/>\n";
    html += "<input type=submit name=output value=search /><br/>\n";
    html += "</form>\n";
    WebView webView = new WebView(context);
    webView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new WebViewClient());
    webView.loadDataWithBaseURL("http://www.google.com", html, "text/html", "UTF-8", null);
    linearLayout.addView(webView);
    return linearLayout;
}

public void showWithAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder
                .setTitle("With AlertDialog")
                .setView(createLinearLayout(getActivity()));
            return builder.create();
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}

public void showWithoutAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            getDialog().setTitle("Without AlertDialog");
            getDialog().setCanceledOnTouchOutside(false);
            return createLinearLayout(getActivity());
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}
0
Stephen Quan

こんにちはPrepbggは、実際にあなたがやったことの代わりの方法があります。実際には、ArrayAdapter内で私のものを使用する必要がありました。私がしたことは、アクティビティのコンテキストをarrayadapterに渡し、それを呼び出してgetWindow()にアクセスしました。

NoteArrayAdapter(Activity _activity, int _layout, ArrayList<Note> _notes, Context _context) {
  callingNoteListObj = (NoteList) _context;
}

// withiin getView

callingNoteListObj.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

// within parent activity's onCreate()
thisObject = this;

//within my parent activity's fillData() (NoteList)
adapter =  new NoteArrayAdapter(activity, R.layout.channel_note_list_item, noteList, thisObject);
0
wired00

。setView()は、ダイアログにキーボードを自動的に表示します。 EditText自体の「最終」に注意してください。重要!

AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Random Title...");
alert.setMessage("Type a name");

final EditText input = new EditText(this);

//Set input focus (which opens the Android  soft keyboard)
alert.setView(input);   
input.setHint("My Name is...");
//Set keyboard type
input.setInputType(InputType.TYPE_CLASS_TEXT); 

//add button onclick handlers...

alert.show();

多くの人がすべての機能で本当にそれをやりすぎていると思います...これはかなり普遍的で素晴らしい仕事です。そして、それはあなたのコードを膨らませません。

0
Kevin Loring

これはさまざまな場所から呼び出されたアラートダイアログで機能することがわかりました

        case R.id.birthyear:
        case R.id.ymax:
            input.setInputType(InputType.TYPE_CLASS_NUMBER);
            break;

他のこともたくさん試しました。繊細そうです。

0
user462990