聚焦edittext时如何显示软键盘


461

我想在EditText焦点对准时自动显示软键盘(如果设备没有物理键盘),并且有两个问题:

  1. Activity显示my 时,我EditText处于聚焦状态,但未显示键盘,我需要再次单击它以显示键盘(在显示my时应显示它Activity)。

  2. 当我在键盘上单击“完成”时,将关闭键盘,但EditText保持焦点,并且您不想要(因为我的编辑已完成)。

要恢复,我的问题是在iPhone上有更多类似的东西:它使键盘与我的EditText状态保持同步(集中/不集中),并且如果有物理键盘,当然也不会显示软键盘。


我只有一个基本的EditText,例如:<EditText android:id =“ @ + id / myEditText” android:layout_width =“ fill_parent” android:layout_height =“ wrap_content” android:imeOptions =“ actionDone” />这:EditText editTxt =(EditText)findViewById(R.id.myEditText); editTxt.requestFocus();
Ludovic Landry,

2
这比本文中的任何答案都对我有更好的帮助:stackoverflow.com/a/2418314/1491212
Armel Larcier 2013年

Answers:


628

要强制显示软键盘,可以使用

EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
yourEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

而要消除对的关注EditText,可悲的是,您需要一个假人View来获取焦点。

我希望这有帮助


要关闭它,您可以使用

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);

这适用于在对话框中使用它

public void showKeyboard(){
    InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

public void closeKeyboard(){
    InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}

2
如果执行此操作,则活动显示时(很好)会显示软键盘,但是当我的焦点离开EditText并转到例如Button时,键盘会停留(不好)。
Ludovic Landry,

157
在已经具有焦点的对话框中使用EditText对我不起作用。不知道为什么。
马提亚斯

10
@AbdellahBenhammou,也许在显示软输入之前执行一次requestFocus调用您的编辑文本可能会解决您的问题。它对我有用。
r1k0

18
@AbdellahBenhammou,请在DialogFragment的onCreate()中执行此操作:getDialog()。getWindow()。setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
菲利普(Phillip)

22
仅连接工作yourEditText.requestFocus():如这里所描述stackoverflow.com/questions/8991522/...
的Vivek Pandey的

231

我有同样的问题。在editText可见性从GONE更改为VISIBLE后,我必须立即设置焦点并显示软键盘。我使用以下代码实现了这一点:

new Handler().postDelayed(new Runnable() {

    public void run() {
//        ((EditText) findViewById(R.id.et_find)).requestFocus();
//              
        EditText yourEditText= (EditText) findViewById(R.id.et_find);
//        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//        imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

        yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , 0, 0, 0));
        yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));                           
    }
}, 200);

它对我来说有100ms的延迟,但是没有任何延迟或只有1ms的延迟而失败。

代码的注释部分显示了另一种方法,该方法仅在某些设备上有效。我在操作系统版本2.2(仿真器),2.2.1(真实设备)和1.6(仿真器)上进行了测试。

这种方法减轻了我很多痛苦。


48
我不知道什么东西可以同时变得如此丑陋和如此美丽。非常感谢!
mkerley 2012年

15
@jellyfish可以模拟上的点击EditText。对于其他阅读此内容的人,Handler除了创建一个新控件之外,您还可以View.postDelayed()yourEditText小部件本身上使用方法。
Tony Chan

5
这是一个hack-David Chandler的更好解决方案。
Ben Bederson

4
如果David Chandler的解决方案可在所有Android版本/设备上使用,并且对于VISIBILITY刚刚从GONE更改为VISIBLE的情况,则是-您应改用他的解决方案。
Mike Keskinov

3
同意 您知道更好的解决方案适用于所有Android版本吗?
Mike Keskinov 2013年

162

要使键盘出现,请使用

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

与直接调用InputMethodManager相比,此方法更可靠。

要关闭它,请使用

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

12
有人可以解释一下为什么这比直接调用更可靠InputMethodManager吗?(与raukodraug的解决方案不同,它不起作用。)
马修·奎罗斯

5
也不适合我。在Android 2.3.5中工作。raukodraug的解决方案确实对我有用。搜索版本依赖性,但找不到版本依赖性。
雨果·洛格曼斯

2
这在Android 4.4.2中为我工作。选择作为该帖子解决方案的InputMethodManager方法对我不起作用。
2014年

在答案中使用该方法后,我将其附加并起作用,但没有它,则无法起作用。thanx
Manny265

2
在Android 4.4.2中不适用于我。它显示了键盘,但没有隐藏它。
约翰·史密斯

87

如果没有其他效果,则强制显示它

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

然后,如果您想关闭它,例如在onPause()中,可以调用:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

4
你说得对,@ Bolling!当其他方法无效时,您的代码救了我。谢谢!
威廉·派肖

3
您的代码是唯一为我工作的代码,我在此页面上尝试了所有解决方案!非常感谢!
Mattia Ruggiero

4
不要强迫它。在某些情况下,当您从前景转到背景时,键盘会保留在那儿,因为您强行使用了它。这是一个零散的问题,但我已经在三星二人组上看到了。
j2emanue

通常,我总是有关闭键盘onPause()的代码,因为即使您没有强行按下它,它也会卡住。
Bolling

确实有效,但是当移至其他屏幕时,它仍保持打开状态
Sithu

75

以下代码摘自Google 4.1的SearchView源代码。似乎可以正常使用,在较小版本的Android上也可以。

private Runnable mShowImeRunnable = new Runnable() {
    public void run() {
        InputMethodManager imm = (InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        if (imm != null) {
            imm.showSoftInput(editText, 0);
        }
    }
};

private void setImeVisibility(final boolean visible) {
    if (visible) {
        post(mShowImeRunnable);
    } else {
        removeCallbacks(mShowImeRunnable);
        InputMethodManager imm = (InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindowToken(), 0);
        }
    }
}

然后,此外,在创建控件/活动时,需要添加以下代码。(在我的情况下,它是一个复合控件,而不是活动)。

this.editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    public void onFocusChange(View v, boolean hasFocus) {
        setImeVisibility(hasFocus);
    }
});

谢谢!它的运作异常出色。在我一直阅读的所有答案和主题中,这都是我比较满意的解决方案。

37
:-D setImeVisibility(hasFocus)
Matthias 2013年

我尝试了这种方法,因为我实际上是在“滚动自己的搜索视图”(不想这样做,但是有原因)。这对我有用,除了活动开始时。我向活动添加了android:windowSoftInputMode =“ alwaysVisible”,并且已经在编辑文本上调用了requestFocus()。像冠军一样工作。
javahead76 2013年

任何想法需要removeCallbacks(mShowImeRunnable)吗?我以为一旦选择了可运行对象以从队列中运行,它也会同时从队列中删除吗?
Cheok Yan Cheng

1
在尝试了几种变体之后,这是唯一对我稳定运行的变体(Android 4.42)。Thx
John J Smith

34

android:windowSoftInputMode="stateAlwaysVisible" ->在清单文件中。

edittext.requestFocus(); ->在代码中。

这将打开软键盘,随着活动的出现,编辑文本将在该软键盘上请求焦点。


2
这将在创建活动时打开键盘。
xpto

没有回答问题,但帮助了我:)
S.Thiongane 2013年

在API 22中打开没有requestfocus的密钥
David

适用于我的情况。我想知道为什么仅来自xml的request focus属性也需要提及manifest
sud007

30

我最近在一些简单的情况下使用下面的代码有些运气。我还没有完成所有测试,但是...

EditText input = (EditText) findViewById(R.id.Input);
input.requestFocus();    
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , 0, 0, 0));
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));

并显示键盘。


就我而言,我有一个添加一些可选信息的按钮。在button.onClick处理程序中,添加了以上代码,以强制软键盘出现,以输入可选信息。Droid 2.2.2
Dent

这是一个很好的解决方案,但不要忘记您应该创建一个MotionEvent对象,并在使用后对其调用recycle(),以供以后的调用方重新使用。
jimbob 2014年

你只需要一个dispatchTouchEvent()与ACTION_UP作为参数..
穆罕默德·朱奈德

15

您可以尝试强制显示软键盘,它对我有用:

...
dialog.show();
input.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

1
这对我有用...我已经尝试过这些InputMethodManager imm =(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(名称,inputMethodManager.SHOW_IMPLICIT); 或getWindow()。setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);或 但他们都没有工作。
居纳伊居尔泰金

10

有时raukodraug的答案不起作用。我以这种方式进行了一些试验和错误:

public static void showKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }
}

public static void hideKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }
}

EditText部分:

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                hideKeyboard(getActivity());
            } else {
                showKeyboard(getActivity());
            }
        }
    });

1
这是在Android 5上对我有效的唯一解决方案
user1021430

10

要隐藏键盘,请使用以下键盘:

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

并显示键盘:

getActivity().getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

对于DialogFragment,您可以在Override中调用它onStart(),也可以getDialog().getWindow()用作的替代getActivity().getWindow()
Mr-IDE

10

对于Kotlin,只需使用以下扩展名:

fun EditText.showKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

fun EditText.hideKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(this.windowToken, 0)
}

正是我想要的。
lasec0203

8

对于片段,请确保其正常工作:

 displayName = (EditText) view.findViewById(R.id.displayName);
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

7

showSoftInput 根本没有为我工作。

我认为我需要设置输入模式:(在清单的“活动”组件中)

android:windowSoftInputMode="stateVisible" 

6

相信与否,当我发现“活动”动画可以禁用“软键盘”时,解决了我的“软键盘”问题。当您用

i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);

overridePendingTransition(0, 0);

它可以隐藏软键盘,并且无法显示它。


6

我在各种不同情况下都遇到了同样的问题,在某些情况下我发现了解决方案,但在另一些情况下却不起作用,因此这是一种组合解决方案,在我发现的大多数情况下都可以使用:

public static void showVirtualKeyboard(Context context, final View view) {
    if (context != null) {
        final InputMethodManager imm =  (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        view.clearFocus();

        if(view.isShown()) {
            imm.showSoftInput(view, 0);
            view.requestFocus();
        } else {
            view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    view.post(new Runnable() {
                        @Override
                        public void run() {
                            view.requestFocus();
                            imm.showSoftInput(view, 0);
                        }
                    });

                    view.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    view.removeOnAttachStateChangeListener(this);
                }
            });
        }
    }
}

6
editText.post(new Runnable() {
    @Override
    public void run() {
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
    }
});

6

我将这里的所有内容结合起来,对我来说它是有效的:

public static void showKeyboardWithFocus(View v, Activity a) {
    try {
        v.requestFocus();
        InputMethodManager imm = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
        a.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


5

代码片段。。。

public void hideKeyboard(Context activityContext){

    InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    //android.R.id.content ( http://stackoverflow.com/a/12887919/2077479 )
    View rootView = ((Activity) activityContext)
            .findViewById(android.R.id.content).getRootView();

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

public void showKeyboard(Context activityContext, final EditText editText){

    final InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    if (!editText.hasFocus()) {
        editText.requestFocus();
    }

    editText.post(new Runnable() {
        @Override
        public void run() {
            imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
        }
    });
}

5

Kotlin 用于显示键盘焦点的扩展名。

这是先前的响应的组合,这些响应太长或不完整。

此扩展程序在消息队列上发布了一个可运行项,该消息队列在请求焦点后显示了软键盘:

fun View.showSoftKeyboard() {
    post {
        if (this.requestFocus()) {
            val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
        }
    }
}

以后在需要时从任何视图调用它:

editText.showSoftKeyboard()


4
final InputMethodManager keyboard = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

4

在清单中:

android:windowSoftInputMode="stateAlwaysVisible"-最初推出的键盘。 android:windowSoftInputMode="stateAlwaysHidden" -最初隐藏的键盘。

我也喜欢使用,"adjustPan"因为当键盘启动时,屏幕会自动调整。

 <activity
      android:name="YourActivity"
      android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>

4

只需在您的EditText视图中添加以下行:

android:isScrollContainer="true"

和TADA-键盘开始自动显示!

我遇到了类似的问题,并发现了这个简单而奇怪的解决方案。

正如user3392439在此已经提到的那样,键盘的外观在某种程度上与XML文件中滚动组件的存在紧密地联系在一起。

即使在同一XML中包含上述行的另一个 EditText视图的出现,也使键盘出现,无论哪个EditTexts当前处于焦点。

如果您的XML文件中至少有一个包含滚动组件的可见视图-键盘将自动显示在焦点上。

如果没有滚动,则需要单击EditText使键盘出现。


这很奇怪,但是它确实可以工作-我试图requesFocus()从点击处理程序中访问,这是除显式showSoftInput SHOW_FORCED之外的唯一方法
绘制

真是的,谢谢。不知道为什么它起作用,但是我已经在不同制造商的8种设备上对其进行了测试,并且每次都能起作用!
Antonio Vlasic

3

上面给出的所有解决方案(如果活动中具有单个编辑,则附加到EditText的OnFocusChangeListener.onFocusChange侦听器中的InputMethodManager交互都可以正常工作。

就我而言,我有两个修改。

 private EditText tvX, tvY;
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 tvX.setOnFocusChangeListener(this);
    tvY.setOnFocusChangeListener(this);

@Override
public void onFocusChange(View v, boolean hasFocus) {       
    InputMethodManager imm =  (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(tvX.hasFocus() || tvY.hasFocus()) {            
        imm.showSoftInput(v, 0);            
    } else {
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);         
    }       
};

我观察到,使用hasFocus = true(显示键盘)的tvX触发了onFocusChange,但是使用hasFocus = true(隐藏键盘)的tvY触发了onFocusChange。最后,看不到键盘。

如果“如果EditText文本具有焦点,则显示键盘”中的常规解决方案应具有正确的说明


3

在Activity的onResume()部分中,您可以调用方法BringKeyboard();。

 onResume() {
     EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
     bringKeyboard(yourEditText);
 }


  protected boolean bringKeyboard(EditText view) {
    if (view == null) {
        return false;
    }
    try {
      // Depending if edittext has some pre-filled values you can decide whether to bring up soft keyboard or not
        String value = view.getText().toString();
        if (value == null) {
            InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
            return true;
        }
    } catch (Exception e) {
        Log.e(TAG, "decideFocus. Exception", e);
    }
    return false;
  }

什么WidgetUtils.showKeyboard啊 这是最重要的一点。
TWiStErRob 2015年

2

没有答案对我有用。这是一个简单的方法。

searchEditText.setVisibility(View.VISIBLE);
                final Handler handler=new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        searchEditText.requestFocus();
                    }
                }, 400);

只是将requestFocus()方法延迟了400ms。


非常感谢,它需要一些延迟才能显示键盘...
hkh114

1

我发现了一个奇怪的行为,因为在我的一个应用程序中,进入活动时软键盘会自动显示(onCreate中有editText.requestFocus())。

在进一步挖掘时,我发现这是因为布局周围存在ScrollView。如果删除ScrollView,其行为将与原始问题说明中所述:仅在单击已经集中的editText时,软键盘才会显示。

如果它对您不起作用,请尝试放入ScrollView -仍然无害。


1

使用视图动画时,我遇到了类似的问题。因此,我放置了一个动画侦听器,以确保在尝试对显示的edittext请求键盘访问之前,我将等待动画结束

    bottomUp.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            if (textToFocus != null) {
                // Position cursor at the end of the text
                textToFocus.setSelection(textToFocus.getText().length());
                // Show keyboard
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(textToFocus, InputMethodManager.SHOW_IMPLICIT);
            }
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    });

1

我同意raukodraug的用法,在swithview中使用,您必须要求/明确这样的焦点:

    final ViewSwitcher viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
    final View btn = viewSwitcher.findViewById(R.id.address_btn);
    final View title = viewSwitcher.findViewById(R.id.address_value);

    title.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            viewSwitcher.showPrevious();
            btn.requestFocus();
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(btn, InputMethodManager.SHOW_IMPLICIT);
        }
    });

    // EditText affiche le titre evenement click
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            btn.clearFocus();
            viewSwitcher.showNext();
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(btn.getWindowToken(), 0);
            // Enregistre l'adresse.
            addAddress(view);
        }
    });

问候。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.