Displaying soft keyboard whenever AlertDialog.Builder object is opened
My code for opening an input dialog reads as follows:
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(开发者_StackOverflow社区"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);
This works fine except that I have to tap the text entry line before the soft keyboard appears.
Following the advice given here I have tried inserting:
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);
}
}
});
but Eclipse objects that "the method getWindow() is not defined for the type AlertDialog.Builder".
It seems that the setOnFocusChangeListener code works for an AlertDialog object but not an AlertDialog.Builder. How should I modify my code to make the soft keyboard appear automatcially.
As long as you always need to show the keyboard immediately once the dialog opens rather than once a specific form widget inside gets focus (for instance, if your dialog just shows an EditText
and a button), you can do the following:
AlertDialog alertToShow = alert.create();
alertToShow.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
alertToShow.show();
Rather than calling .show()
on your builder immediately, you can instead call .create()
which allows you to do some extra processing on it before you display it onto the screen.
This is in response to miannelle.
The following method is called when a menu option is selected:
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();
}
The textentryalertdialog.xml file defines a linear layout containing
TextView android:id="@+id/messagetext" ...
EditText android:id="@+id/my_edittext" ...
Button android:id="@+id/OKButton" ...
Button android:id="@+id/CancelButton" ...
I hope this helps.
With the encouragement of Mur Votema (see his answer above) I have answered my question by building a custom dialog based on the Dialog class. Unlike an alert based on AlertDialog.Builder such a custom dialog does accept the getWindow().setSoftInputMode(...) command and therefore allows the soft keyboard to be displayed automatically.
For guidance on building a custom dialog I found this web page and this especially helpful.
try using view
v.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Have you tried to set focus on your EditText -> inputBox.requestFocus() or something like that?
If you want to pop up dialog box along with soft key pad, so that user could free from tap on edit text inside dialog to show keypad, for example if you are going to take some value from dialog box, then use this simple code, it will solve your problem.
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();
}
try using inputBox
inputBox.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
I know, this Question is really old, but since I've tried about 20 different so called 'solutions', I will post, what actually only worked for me finally.
This answer is based on the answer of Pir Fahim Shah, who pointed me in the right direction (Thanks):
Make sure, you put this in the onCreate of your activity, so that forced keyboards are being hidden, when dialog is closed:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
then create a dialog like this:
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();
I think you almost had it working in your original question. Try creating a final AlertDialog
to call getWindow()
on, e.g.
// 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);
}
}
});
I've tested this code and the keyboard now appears automatically on most of my devices, including:
- Samsung Galaxy Tab OS 2.2
- Samsung Galaxy S OS 2.1
- HTC Sensation OS 2.3.4
Some other comments on this solution:
1) Check if you've got anything in your XML already to request the focus, as that may stop this code working (according to Ted in the question you link to).
2) This code doesn't seem to work on my HTC G2 running OS 2.3.4. I guess this is because it has a physical keyboard, and maybe the WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
option doesn't work with it?
I also tried SOFT_INPUT_STATE_VISIBLE (without the ALWAYS), but that stopped the keyboard appearing automatically.
3) You may also want to add code so the user can press the Done button on the keyboard to submit the changes, e.g.
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;
}
});
I create an AlertDialog
and use a custom view which contains an EditText
. And I want the soft keyboard to be shown when the dialog is shown and to be hidden whether the user clicks OK button or somewhere outside the dialog.
This piece of code is from androidx.perference.PreferenceDialogFragmentCompat
and I clean up a little.
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();
You don't need to modify Manifest. It automatically focuses to the EditText
and will be dismissed whether you click dialog action buttons or somewhere outside the dialog.
Hi Prepbgg there is actually an alternative way to what you've done. I actually had to use mine within my ArrayAdapter. What i did was pass the context of the activity into the arrayadapter then call it to access getWindow() something like this:
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);
In the following code snippet I show how to host an arbitrary LinearLayout
in a DialogFragment
. One using AlertDialog
(where the soft keyboard doesn't work) and another way without using AlertDialog
(where the soft keyboard does work!):
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");
}
I found this worked in an Alert Dialog called from different places
case R.id.birthyear:
case R.id.ymax:
input.setInputType(InputType.TYPE_CLASS_NUMBER);
break;
Mind you I tried lots of other things too. Seems delicate.
.setView() will automatically bring up the keyboard in a dialog. Note the "final" on the EditText itself. IMPORTANT!
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();
I think a lot of people are really overdoing it with all the functions... This is fairly universal and work great. And it won't bloat your code.
精彩评论