ChatGPT解决这个技术问题 Extra ChatGPT

Show keyboard for edittext when fragment starts

When my fragment starts, I want my edittext to be in focus/let user to just start typing in it. I am able to get it in focus with requestFocus(), but I cannot get the keyboard to show up.

I have tried both this:

edit = (EditText) view.findViewById(R.id.search);
edit.requestFocus();
InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imgr.showSoftInput(edit, 0);

and

edit = (EditText) view.findViewById(R.id.search);
InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imgr.showSoftInput(edit, 0);
edit.requestFocus();

How can I get the keyboard to show up for EditText?

My reputation is too low to comment the question. I answered here with a method to control when to show or hide the keyboard
Check the recommended Answer : stackoverflow.com/a/60666198/6903609

S
Sam

Does this work?

imgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

If you have trouble closing it use one other these methods
This feels like a workaround. The correct procedure should be either as OP suggested or to call imgr.showSoftInput(getView(), InputMethodManager.SHOW_IMPLICIT). Toggle will actually close the keyboard if it happens to already be open. The solution described is the only one I've gotten to work though, so is this a bug in the framework? Better solution or explanation would be appreciated.
@Nilzor I know your comment is a bit old, but recently had the same issue and found this bug report code.google.com/p/android/issues/detail?id=25812 . May be related, haven't seen much from the Android team on it though, so not sure it has priority.
@Nilzor - I tried your code, for me it doesn't work when I open the fragment for the first time, but it works the second time. Any hint ? Thanks!
Confirming it works on Fragment.onCreateView every time the Fragment comes onto the screen. Thank you!
I
Ilya

You can try this

@Override
public void onResume() {
    super.onResume();
    edit.post(new Runnable() {
        @Override
        public void run() {
            edit.requestFocus();
            InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imgr.showSoftInput(edit, InputMethodManager.SHOW_IMPLICIT);
        }
    });
}

This Solution worked with me although i didnt need to do the edit.post thing, i only added the 3 lines inside your run() to the resume method directly .
B
BierDav

Since using showSoftInput doesn't work for all cases and after trying some of the solutions mentioned here, like:

if (binding.account.requestFocus()) {
  requireActivity().getWindow()
      .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}

I finally made it work using:

if (binding.account.requestFocus()) {
  ((InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(
      InputMethodManager.SHOW_FORCED,
      InputMethodManager.HIDE_IMPLICIT_ONLY
  );
}

Since:

 binding.account.requestFocus()

only request the focus for the EditText (it doesn't open the keyboard)

and

((InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(
      InputMethodManager.SHOW_FORCED,
      InputMethodManager.HIDE_IMPLICIT_ONLY
  );

is the only solution that appears to be working correctly to show the keyboard (and the most voted one)

Good luck! :-)


this works, it opens the keyboard, But how do I close the keyboard when dismissing my DialogFragment?
Right now I'm not able to give you an answer since the code is in another project. But I'm pretty sure you will find something in StackOverflow :-)
R
Rafols

I have helpful extension for that:

fun EditText.showKeyboard() {
    if (requestFocus()) {
        (getActivity()?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager)
            .showSoftInput(this, SHOW_IMPLICIT)
        setSelection(text.length)
    }
}

You will also need this one:

fun View.getActivity(): AppCompatActivity?{
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}

oh love Kotlin ext! :)
A
Amin Keshavarzian

After trying all solutions here and on other questions related, Here's the method that works for me:

editText.postDelayed(Runnable { showKeyboard(activity, editText)} , 50)


fun showKeyboard(activity: Activity, editText: EditText) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    editText.requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

The fun fact is when you call it without postDeleayed it won't work, even if you just delay it for 1 millisecond it still won't work :D

You can also use it as an extension like this:

fun EditText.showKeyboard(activity: Activity) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

if you don't like to pass activity as a parameter, you use this extension function as @Rafols suggests:

fun View.getActivity(): AppCompatActivity? {
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}

then your method will look like this:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

also if you have a text already in your EditText, its better set selection at the end of your existing text:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
    setSelection(length())
}

and if you want to start it when fragment starts:

override fun onResume() {
    super.onResume()
    editText.postDelayed(Runnable { editText.showKeyboard()} , 50)
}

R
Rubber Duck
    @Override
public void onHiddenChanged (boolean hidden)
{
    super.onHiddenChanged(hidden);

    if(hidden)
    {
        hideKeyboard(yourView);
    }
    else
    {
        toggleKeyboard(yourView);
    }
}

    public static void toggleKeyboard(View v)
{
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    v.requestFocus();

    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_NOT_ALWAYS);
}

public static void hideKeyboard(View v)
{
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

Y
Yessy

EditText.requestFocus() + InputMethodManager.showSoftInput() = Show IME for EditText

use EditText.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null) in Fragment.onViewCreated() instead

    void maybeShowInputMethod() {
        // use addOnPreDrawListener instead of addOnGlobalLayoutListener
        // because execute sequence: onGlobalLayout-> Restore focus -> onPreDraw
        getView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            @Override
            public boolean onPreDraw() {
                // TODO Auto-generated method stub
                getView().getViewTreeObserver().removeOnPreDrawListener(this);

                // always requestFocus when fragment enter or show
                getView().requestFocus();
                final View currentFocus = getView().findFocus();
                if ((currentFocus != null) && currentFocus.onCheckIsTextEditor()) {
                    Log.d(TAG, "maybeShowInputMethod:: currentFocus=" + currentFocus);
                    currentFocus.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null);
                }
                return true;
            }
        });
    }

or create subclass of EditText and override public InputConnection onCreateInputConnection(EditorInfo editorInfo)

public class ImeAwareEditText extends EditText {
private boolean mHasPendingShowSoftInputRequest;
final Runnable mRunShowSoftInputIfNecessary = () -> showSoftInputIfNecessary();

public ImeAwareEditText(Context context) {
    super(context, null);
}

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

public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr,
        int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}

/**
 * This method is called back by the system when the system is about to establish a connection
 * to the current input method.
 *
 * <p>This is a good and reliable signal to schedule a pending task to call
                                                                                                                                                                                                                     52,6          Top
 *
 * <p>This is a good and reliable signal to schedule a pending task to call
 * {@link InputMethodManager#showSoftInput(View, int)}.</p>
 *
 * @param editorInfo context about the text input field.
 * @return {@link InputConnection} to be passed to the input method.
 */
@Override
public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
    final InputConnection ic = super.onCreateInputConnection(editorInfo);
    if (mHasPendingShowSoftInputRequest) {
        removeCallbacks(mRunShowSoftInputIfNecessary);
        post(mRunShowSoftInputIfNecessary);
    }
    return ic;
}

private void showSoftInputIfNecessary() {
    if (mHasPendingShowSoftInputRequest) {
        final InputMethodManager imm =
                getContext().getSystemService(InputMethodManager.class);
        imm.showSoftInput(this, 0);
        mHasPendingShowSoftInputRequest = false;
    }
}

public void scheduleShowSoftInput() {
    final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
    if (imm.isActive(this)) {
        // This means that ImeAwareEditText is already connected to the IME.
        // InputMethodManager#showSoftInput() is guaranteed to pass client-side focus check.
        mHasPendingShowSoftInputRequest = false;
        removeCallbacks(mRunShowSoftInputIfNecessary);
        imm.showSoftInput(this, 0);
        return;
    }

    // Otherwise, InputMethodManager#showSoftInput() should be deferred after
    // onCreateInputConnection().
    mHasPendingShowSoftInputRequest = true;
}
}

X
X-Black...

Kotlin

To automatically show/hide the keyboard in fragment...

override fun onResume() {
    super.onResume()

    requireView().edit_text_ID.showKeyboard()

    requireView().edit_text_ID.setOnFocusChangeListener { _, hasFocus ->
     if (!hasFocus){
        hideKeyboardFrom(requireContext(), requireView())
     }
    }
}

fun EditText.showKeyboard() {
    if (requestFocus()) {
        (activity?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager)
            .showSoftInput(this, SHOW_IMPLICIT)
        setSelection(text.length)
    }
}

fun hideKeyboardFrom(context: Context, view: View) {
    val imm =
        context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(view.windowToken, 0)
}

A little piesce of info here.


D
DiscDev

Another way to make the keyboard open when your fragment starts is to call requestFocus() in onCreateView and react accordingly by opening the keyboard if and only if the EditText is focusable.

if(this.editText.requestFocus())
{
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}

s
sud007

Simply, using adding 2 lines will work like a charm:

If using XML

android:focusable="true"
android:focusableInTouchMode="true"

Else in Java:

view.setFocusableInTouchMode(true);
view.requestFocus();

Dear random visitor, please provide an explanation for the downvote. That would help me learn what was wrong in this solution because this worked for me.
d
daniilxt

Kotlin

The keyboard opens when you start the fragment

    override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val fragmentView = inflater.inflate(R.layout.fragment_main, container, false)

    activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

    return fragmentView
}

s
shubomb

Below delay code work for me

editTextLabel.postDelayed(new Runnable() {
                @Override
                public void run() {
                    InputMethodManager keyboard = (InputMethodManager) activity
                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    keyboard.showSoftInput(editTextLabel, 0);
                }
            }, 1000);

P
Purgarcita

As Nilzor said this works

imgr.showSoftInput(getView(), InputMethodManager.SHOW_IMPLICIT)

and I agree it is a best solution than toogleSoftInput


A
Abror Esonaliev

this article helped me

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
{
  View view = inflater.inflate(R.layout.fragment_edit_name, container);
  editText = (EditText) view.findViewById(R.id.txt_yourName);
  editText.requestFocus();
  getDialog().getWindow().setSoftInputMode(
                       LayoutParams.SOFT_INPUT_STATE_VISIBLE);
   return view;
}

https://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/