可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I\'m showing an input box using AlertDialog
. The EditText
inside the dialog itself is automatically focused when I call AlertDialog.show()
, but the soft keyboard is not automatically shown.
How do I make the soft keyboard automatically show when the dialog is shown? (and there is no physical/hardware keyboard). Similar to how when I press the Search button to invoke the global search, the soft keyboard is automatically shown.
回答1:
You can create a focus listener on the EditText
on the AlertDialog
, then get the AlertDialog
\'s Window
. From there you can make the soft keyboard show by calling setSoftInputMode
.
final AlertDialog dialog = ...;
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
回答2:
For showing keyboard use:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
For hiding keyboard use:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
回答3:
You can request a soft keyboard right after creating the dialog (test on SDK - r20)
// create dialog
final AlertDialog dialog = ...;
// request keyboard
dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
回答4:
I had the same problem and solved it with the following code. I\'m not sure how it will behave on a phone with hardware keyboard.
// TextEdit
final EditText textEdit = new EditText(this);
// Builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(\"Enter text\");
alert.setView(textEdit);
alert.setPositiveButton(\"Ok\", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = textEdit.getText().toString();
finish();
}
});
alert.setNegativeButton(\"Cancel\", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
// Dialog
AlertDialog dialog = alert.create();
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
}
});
dialog.show();
回答5:
I found this example http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html. Add the following code just before alert.show()
.
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
回答6:
<activity
...
android:windowSoftInputMode=\"stateVisible\" >
</activity>
or
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
回答7:
Snippets of code from other answers work, but it is not always obvious where to place them in the code, especially if you are using an AlertDialog.Builder
and followed the official dialog tutorial because it doesn\'t use final AlertDialog ...
or alertDialog.show()
.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Is preferable to
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
Because SOFT_INPUT_STATE_ALWAYS_VISIBLE will hide the keyboard if the focus switches away from the EditText, where SHOW_FORCED will keep the keyboard displayed until it is explicitly dismissed, even if the user returns to the homescreen or displays the recent apps.
Below is working code for an AlertDialog created using a custom layout with an EditText defined in XML. It also sets the keyboard to have a \"go\" key and allows it to trigger the positive button.
alert_dialog.xml:
<RelativeLayout
android:id=\"@+id/dialogRelativeLayout\"
xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\" >
<!-- android:imeOptions=\"actionGo\" sets the keyboard to have a \"go\" key instead of a \"new line\" key. -->
<!-- android:inputType=\"textUri\" disables spell check in the EditText and changes the \"go\" key from a check mark to an arrow. -->
<EditText
android:id=\"@+id/editText\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:layout_marginTop=\"16dp\"
android:layout_marginLeft=\"4dp\"
android:layout_marginRight=\"4dp\"
android:layout_marginBottom=\"16dp\"
android:imeOptions=\"actionGo\"
android:inputType=\"textUri\"/>
</RelativeLayout>
AlertDialog.java:
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
public class CreateDialog extends AppCompatDialogFragment {
// The public interface is used to send information back to the activity that called CreateDialog.
public interface CreateDialogListener {
void onCreateDialogCancel(DialogFragment dialog);
void onCreateDialogOK(DialogFragment dialog);
}
CreateDialogListener mListener;
// Check to make sure that the activity that called CreateDialog implements both listeners.
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (CreateDialogListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + \" must implement CreateDialogListener.\");
}
}
// onCreateDialog requires @NonNull.
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
LayoutInflater customDialogInflater = getActivity().getLayoutInflater();
// Setup dialogBuilder.
alertDialogBuilder.setTitle(R.string.title);
alertDialogBuilder.setView(customDialogInflater.inflate(R.layout.alert_dialog, null));
alertDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mListener.onCreateDialogCancel(CreateDialog.this);
}
});
alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mListener.onCreateDialogOK(CreateDialog.this);
}
});
// Assign the resulting built dialog to an AlertDialog.
final AlertDialog alertDialog = alertDialogBuilder.create();
// Show the keyboard when the dialog is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
// We need to show alertDialog before we can setOnKeyListener below.
alertDialog.show();
EditText editText = (EditText) alertDialog.findViewById(R.id.editText);
// Allow the \"enter\" key on the keyboard to execute \"OK\".
editText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the \"enter\" button, select the PositiveButton \"OK\".
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Trigger the create listener.
mListener.onCreateDialogOK(CreateDialog.this);
// Manually dismiss alertDialog.
alertDialog.dismiss();
// Consume the event.
return true;
} else {
// If any other key was pressed, do not consume the event.
return false;
}
}
});
// onCreateDialog requires the return of an AlertDialog.
return alertDialog;
}
}
回答8:
Well, this is a pretty old post, still there is something to add.
These are 2 simple methods that help me to keep keyboard under control and they work just perfect:
Show keyboard
public void showKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View v = getCurrentFocus();
if (v != null)
imm.showSoftInput(v, 0);
}
Hide keyboard
public void hideKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View v = getCurrentFocus();
if (v != null)
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
回答9:
Let me point some additional info to the solution of yuku, because I found it hard to get this working! How do I get the AlertDialog object from my AlertDialog.Builder? Well, it\'s the result of my alert.show()
execution:
final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
final EditText input = new EditText(getActivity());
alert.setView(input);
// do what you need, like setting positive and negative buttons...
final AlertDialog dialog = alert.show();
input.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
回答10:
Take a look at this discussion which handles manually hiding and showing the IME. However, my feeling is that if a focused EditText
is not bringing the IME up it is because you are calling AlertDialog.show()
in your OnCreate()
or some other method which is evoked before the screen is actually presented. Moving it to OnPostResume()
should fix it in that case I believe.
回答11:
Yes you can do with setOnFocusChangeListener
it will help you.
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
回答12:
If anyone is getting:
Cannot make a static reference to the non-static method getSystemService(String) from the type Activity
Try adding context to getSystemService call.
So
InputMethodManager imm =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
回答13:
The original question concerns Dialogs and my EditText is on a regular view. Anyhow, I suspect this should work for most of you too. So here\'s what works for me (the above suggested highest rated method did nothing for me). Here\'s a custom EditView that does this (subclassing is not necessary, but I found it convenient for my purposes as I wanted to also grab the focus when the view becomes visible).
This is actually largely the same as the tidbecks answer. I actually didn\'t notice his answer at all as it had zero up votes. Then I was about to just comment his post, but it would have been too long, so I ended doing this post anyways. tidbeck points out that he\'s unsure how it works with devices having keyboards. I can confirm that the behaviour seems to be exactly the same in either case. That being such that on portrait mode the software keyboard gets popped up and on landscape it doesn\'t. Having the physical keyboard slid out or not makes no difference on my phone.
Because, I personally found the behaviour a bit awkward I opted for using: InputMethodManager.SHOW_FORCED
. This works as I wanted it to work. The keyboard becomes visible regardless of the orientation, however, at least on my device it doesn\'t pop up if the hardware keyboard has been slid out.
import android.app.Service;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
public class BringOutTheSoftInputOnFocusEditTextView extends EditText {
protected InputMethodManager inputMethodManager;
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context) {
super(context);
init();
}
private void init() {
this.inputMethodManager = (InputMethodManager)getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
this.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
BringOutTheSoftInputOnFocusEditTextView.this.inputMethodManager.showSoftInput(BringOutTheSoftInputOnFocusEditTextView.this, InputMethodManager.SHOW_FORCED);
}
}
});
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == View.VISIBLE) {
BringOutTheSoftInputOnFocusEditTextView.this.requestFocus();
}
}
}
回答14:
The problem seems to be that since the place where you enter text is hidden initially (or nested or something), AlertDialog is automatically setting the flag WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
so that things don\'t trigger a soft input to show up.
The way that to fix this is to add the following:
(...)
// Create the dialog and show it
Dialog dialog = builder.create()
dialog.show();
// After show (this is important specially if you have a list, a pager or other view that uses a adapter), clear the flags and set the soft input mode
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
回答15:
try and use:
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
回答16:
To show keyboard, for me, I had to do the following
Android TextField : set focus + soft input programmatically
Essentially the solution is the following
@Override
public void onResume() {
super.onResume();
//passwordInput.requestFocus(); <-- that doesn\'t work
passwordInput.postDelayed(new ShowKeyboard(), 325); //250 sometimes doesn\'t run if returning from LockScreen
}
Where ShowKeyboard
is
private class ShowKeyboard implements Runnable {
@Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
//passwordInput.requestFocusFromTouch(); //this gives touch event to launcher in background -_-
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}
After a successful input, I also make sure I hide the keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(getView().getWindowToken(), 0);
回答17:
I created nice kotlin-esqe extension functions incase anyone is interested
fun Activity.hideKeyBoard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
fun Activity.showKeyboard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
回答18:
This is good sample for you :
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:orientation=\"vertical\" >
<ScrollView
android:id=\"@+id/scrollID\"
android:layout_width=\"fill_parent\"
android:layout_height=\"0dip\"
android:layout_weight=\"1\" >
<LinearLayout
android:id=\"@+id/test\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:orientation=\"vertical\" >
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:baselineAligned=\"true\"
android:orientation=\"horizontal\"
android:paddingBottom=\"5dp\"
android:paddingLeft=\"5dp\"
android:paddingRight=\"5dp\"
android:weightSum=\"1\" >
<EditText
android:id=\"@+id/txtInpuConversation\"
android:layout_width=\"0dip\"
android:layout_height=\"wrap_content\"
android:layout_weight=\"0.5\"
android:hint=\"@string/edt_Conversation\" >
<requestFocus />
</EditText>
<Button
android:id=\"@+id/btnSend\"
android:layout_width=\"0dip\"
android:layout_height=\"wrap_content\"
android:layout_weight=\"0.5\"
android:text=\"@string/btn_Conversation\" />
</LinearLayout>
</LinearLayout>
回答19:
Why this answer - Because above solution will show your keyboard but it will not vanish if you click anywhere other that EditText
. So you need to do something to make the keybaord disappear when EditText
loses focus.
You can achieve this by doing the following steps:
Make the parent view(content view of your activity) clickable and focusable by adding the following attributes
android:clickable=\"true\"
android:focusableInTouchMode=\"true\"
Implement a hideKeyboard() method
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY );
}
Lastly, set the onFocusChangeListener of your edittext.
edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
hideKeyboard(v);
}
}
});
回答20:
This is bit tricky. I did in this way and it worked.
1.At first call to hide the soft Input from the window. This will hide the soft input if the soft keyboard is visible or do nothing if it is not.
2.Show your dialog
3.Then simply call to toggle soft input.
code:
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
//hiding soft input
inputManager.hideSoftInputFromWindow(findViewById(android.R.id.content).getWindowToken(), 0);
//show dialog
yourDialog.show();
//toggle soft input
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.SHOW_IMPLICIT);
回答21:
Try this
SomeUtils.java
public static void showKeyboard(Activity activity, boolean show) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if(show)
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
else
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);
}
回答22:
Put these methods in your Util class and use anywhere.
Kotlin
fun hideKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
private fun showKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
Java
public static void hideKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
private static void showKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
回答23:
As horkavlna wrote,
toggle
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
and hide keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
methods work. But show variants don\'t work in my case. So in onCreate()
I put hideKeyboard(editText);
then in onStart()
I write toggleKeyboard(editText);
and in onStop()
I write hideKeyboard(editText);
.
There are three problems:
1) when an application starts with turned off screen it will hide the keyboard,
2) every time you turn on the screen it will show the keyboard,
3) after application finish you can see the keyboard in Android main screen.
After several tests I removed these methods and in AndroidManifest
in activity
tags wrote android:windowSoftInputMode=\"stateVisible\"
or android:windowSoftInputMode=\"stateAlwaysHidden\"
.
回答24:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
I call this in onCreate() to show keyboard automatically, when I came in the Activity.