Android 片段启动时显示edittext的键盘

Android 片段启动时显示edittext的键盘,android,android-edittext,android-softkeyboard,Android,Android Edittext,Android Softkeyboard,当我的片段开始时,我希望我的edittext处于焦点/让用户开始键入它。我可以使用requestFocus()将其对焦,但无法显示键盘 我试过这两种方法: edit = (EditText) view.findViewById(R.id.search); edit.requestFocus(); InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SE

当我的片段开始时,我希望我的edittext处于焦点/让用户开始键入它。我可以使用requestFocus()将其对焦,但无法显示键盘

我试过这两种方法:

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

如何让键盘显示EditText?

这行吗

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

正如尼尔佐所说,这是可行的

imgr.showSoftInput(getView(), InputMethodManager.SHOW_IMPLICIT)
我同意这是比toogleSoftInput更好的解决方案。你可以试试这个

@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);
        }
    });
}

另一种在片段启动时打开键盘的方法是在
onCreateView
中调用
requestFocus()
,并在
EditText
可聚焦时打开键盘

if(this.editText.requestFocus())
{
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
这篇文章帮助了我

@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;
}

因为使用
showSoftInput
并不适用于所有情况,在尝试了此处提到的一些解决方案后,例如:

if (binding.account.requestFocus()) {
  requireActivity().getWindow()
      .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
我终于用实现了:

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

 binding.account.requestFocus()
仅请求
编辑文本的焦点(不打开键盘)

是唯一能够正确显示键盘的解决方案(也是投票最多的解决方案)


祝你好运!:-)

简单地说,使用添加两行将非常有效:

如果使用XML

android:focusable="true"
android:focusableInTouchMode="true"
Java中的Else:

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

我有一个有用的扩展:

fun EditText.showKeyboard() {
    if (requestFocus()) {
        (getActivity()?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager)
            .showSoftInput(this, SHOW_IMPLICIT)
        setSelection(text.length)
    }
}
您还需要这个:

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

在尝试了这里的所有解决方案和其他相关问题后,以下是适合我的方法:

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)
}
有趣的是,如果你不使用postDeleayed来调用它,它将不起作用,即使你只是将它延迟1毫秒,它仍然不起作用:D

您还可以将其用作如下扩展:

fun EditText.showKeyboard(activity: Activity) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}
如果您不想将活动作为参数传递,请使用@Rafols建议的扩展函数:

fun View.getActivity(): AppCompatActivity? {
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}
然后您的方法将如下所示:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}
此外,如果EditText中已有文本,则最好在现有文本的末尾设置选择:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
    setSelection(length())
}
如果您想在片段启动时启动它:

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

EditText.requestFocus()+InputMethodManager.showSoftInput()=显示EditText的输入法

改为在Fragment.onViewCreated()中使用EditText.performAccessibilityAction(AccessibilityNodeInfo.ACTION\u单击,null)


或者创建EditText的子类,并在CreateInputConnection(EditorInfo EditorInfo)上重写公共InputConnection

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;
}
}
公共类IMEAWAREEDITTEXTEXT扩展了EditText{
私有布尔mHappendingShowSoftInputRequest;
最终可运行的mRunShowSoftInputIfNecessary=()->showSoftInputIfNecessary();
公共ImeAwareEditText(上下文){
super(上下文,null);
}
公共ImeAwareEditText(上下文、属性集属性){
超级(上下文,attrs);
}
公共ImeAwareEditText(上下文上下文、属性集属性、int defStyleAttr){
super(上下文、attrs、defStyleAttr);
}
公共ImeAwareEditText(上下文上下文、属性集属性、int defStyleAttr、,
int deftyles){
super(context、attrs、defStyleAttr、defStyleRes);
}
/**
*当系统即将建立连接时,系统将回调此方法
*到当前的输入法。
*
*这是一个很好且可靠的信号,用于安排要调用的挂起任务
52,6顶部
*
*这是一个很好且可靠的信号,用于安排要调用的挂起任务
*{@link InputMethodManager#showsoftwitter输入(视图,int)}

* *@param editorInfo上下文关于文本输入字段。 *@return{@link InputConnection}传递给输入方法。 */ @凌驾 公共输入连接onCreateInputConnection(EditorInfo EditorInfo){ 最终输入连接ic=super.onCreateInputConnection(editorInfo); if(mHasPendingShowSoftInputRequest){ 移除回调(mRunShowSoftInputIfNecessary); 职位(mRunShowSoftInputIfNecessary); } 返回ic; } 私有void showSoftInputIfNecessary(){ if(mHasPendingShowSoftInputRequest){ 最终输入方法管理器imm= getContext().getSystemService(InputMethodManager.class); imm.showsoftwinput(该值为0); mHasPendingShowSoftInputRequest=假; } } public void scheduleShowSoftInput(){ 最终InputMethodManager imm=getContext().getSystemService(InputMethodManager.class); 如果(imm.isActive(本)){ //这意味着ImeAwareEditText已连接到IME。 //InputMethodManager#showSoftInput()保证通过客户端焦点检查。 mHasPendingShowSoftInputRequest=假; 移除回调(mRunShowSoftInputIfNecessary); imm.showsoftwinput(该值为0); 返回; } //否则,InputMethodManager#showSoftInput()应在 //onCreateInputConnection()。 mHasPendingShowSoftInputRequest=真; } }
Kotlin

要在片段中自动显示/隐藏键盘

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)
}
一点点信息。

Kotlin

启动片段时,键盘将打开

    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
}

如果您在关闭它时遇到困难,请使用另一个,这感觉像是一个解决方法。正确的过程应该按照OP的建议,或者调用
imgr.showSoftInput(getView(),InputMethodManager.SHOW\u IMPLICIT)
。如果键盘恰好已经打开,切换实际上会关闭键盘。不过,所描述的解决方案是我唯一可以使用的解决方案,那么这是框架中的一个bug吗?更好的解决方案或解释将不胜感激。@Nilzor我知道您的评论有点陈旧,但最近有相同的问题,并发现了此错误报告。可能与此相关,但安卓团队对其了解不多,因此不确定其优先级。@Nilzor-我尝试了你的代码,对我来说,当我第一次打开该片段时,它不起作用,但它对s起作用
    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;
            }
        });
    }
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;
}
}
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)
}
    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
}