ChatGPT解决这个技术问题 Extra ChatGPT

聚焦edittext时如何显示软键盘

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

当显示我的 Activity 时,我的 EditText 已聚焦但未显示键盘,我需要再次单击它以显示键盘(它应该在显示我的 Activity 时显示)。当我在键盘上单击完成时,键盘被关闭但 EditText 保持焦点并且你不想要(因为我的编辑已完成)。

继续,我的问题是在 iPhone 上有更多类似的东西:它使键盘与我的 EditText 状态(聚焦/不聚焦)保持同步,如果有物理键盘,当然不会显示软键盘。

我只有一个基本的 EditText,例如: 在我的活动中我有这个:EditText editTxt = (EditText) findViewById(R.id.myEditText); editTxt.requestFocus();
这对我的帮助比这篇文章中的任何答案都好:stackoverflow.com/a/2418314/1491212

r
raukodraug

要强制出现软键盘,您可以使用

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

如果我这样做,软键盘会在活动出现时显示(这很好),但是当我的焦点离开 EditText 并转到一个 Button 时,键盘会停留(这很糟糕)。
在已经具有焦点的对话框中使用 EditText 对我不起作用。不知道为什么。
@AbdellahBenhammou,也许在显示软输入之前对您的编辑文本进行 requestFocus 调用可能会解决您的问题。它对我有用。
@AbdellahBenhammou,在 DialogFragment 的 onCreate() 中执行此操作: getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
仅与此处所述的 yourEditText.requestFocus() 一起使用:stackoverflow.com/questions/8991522/…
L
Leonid Ustenko

我有同样的问题。在 editText VISIBILITY 从 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, 0f, 0f, 0));
        yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0f, 0f, 0));                          
    }
}, 200);

它对我有 100 毫秒的延迟,但没有任何延迟或只有 1 毫秒的延迟就失败了。

代码的注释部分显示了另一种方法,该方法仅适用于某些设备。我在 OS 版本 2.2(模拟器)、2.2.1(真实设备)和 1.6(模拟器)上进行了测试。

这种方法为我节省了很多痛苦。


那是天才,迈克。也许是一个扭曲的天才,但“为我工作”。
我不知道有什么东西可以同时如此丑陋和如此美丽。太感谢了!
@jellyfish 这模拟了对 EditText 的点击。对于阅读本文的其他人,您也可以在 yourEditText 小部件本身上使用 View.postDelayed() 方法,而不是创建新的 Handler
这是一个 hack - David Chandler 的更好的解决方案。
如果 David Chandler 的解决方案适用于所有 Android 版本/设备,并且适用于 VISIBILITY 刚刚从 GONE 更改为 VISIBLE 的情况,那么是的 - 您应该改用他的解决方案。
C
Community

要使键盘出现,请使用

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

这种方法比直接调用 InputMethodManager 更可靠。

要关闭它,请使用

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

有人可以解释为什么这比直接调用 InputMethodManager 更可靠吗? (一方面,它不起作用,不像 raukodraug 的解决方案。)
也不适合我。在 Android 2.3.5 中工作。 raukodraug 的解决方案对我有用。搜索版本依赖,但找不到。
这在 Android 4.4.2 中对我有用。选择作为本文解决方案的 InputMethodManager 方法对我不起作用。
在答案中使用该方法后,我附加了它并且它有效,但没有它它不起作用。谢谢
在 Android 4.4.2 中不适用于我。它显示了键盘,但没有隐藏它。
B
Bolling

当没有其他工作时,强制显示它:

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

你是对的,@Bolling!当没有其他工作时,您的代码救了我。谢谢!
您的代码是唯一为我工作的代码,我尝试了此页面上的所有解决方案!非常感谢!
不要强迫它。在某些情况下,当您从前台转到后台时,键盘将保留在那里,因为您强制使用它。这是一个碎片问题,但我在三星二重奏上看到过。
我通常总是有关闭键盘 onPause() 的代码,因为即使你没有强制它,我也看到它卡住了。
这确实有效,但是当移动到其他屏幕时,它仍然保持打开状态
T
TWiStErRob

以下代码来自 Google 的 SearchView 4.1 源代码。似乎可以工作,在较低版本的 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);
    }
});

谢谢!它工作得非常好。从我一直在阅读的有关此问题的所有答案和主题中,这是我更满意的解决方案。
:-D setImeVisibility(hasFocus)
我尝试了这种方法,因为我实际上是在“滚动我自己的搜索视图”(不想这样做,但有原因)。除了在活动启动时,这对我有用。我将 android:windowSoftInputMode="alwaysVisible" 添加到活动中,并且已经在编辑文本上调用了 requestFocus()。像冠军一样工作。
在尝试了几种变体之后,这是唯一对我有效的变体(Android 4.42)。谢谢
+1 - 关于确切的问题,这是最完整和正确的答案,应该是公认的答案
S
Shreyos Adikari

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

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

这将打开软键盘,当活动出现时,编辑文本具有请求焦点。


这会在 Activity 创建时打开键盘。
没有回答问题,但帮助了我:)
在 api 22 中打开没有 requestfocus 的密钥
适用于我的情况。我想知道为什么仅来自 xml 的请求焦点属性也需要在 manifest 中提及!
L
Leonid Ustenko

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

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

很快键盘就出现了。


就我而言,我有一个按钮来添加一些可选信息。在 button.onClick 处理程序中,添加了上述代码以强制出现软键盘以输入可选信息。机器人 2.2.2
这是一个很好的解决方案,但不要忘记您应该创建一个 MotionEvent 对象并在使用后对其调用 recycle() ,以供以后的调用者重新使用。
您只需要一个以 ACTION_UP 作为参数的 dispatchTouchEvent() ..
V
Vadim Zin4uk

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

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

这对我有用......我试过这些 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(name, inputMethodManager.SHOW_IMPLICIT);或 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);但他们都没有工作。
b
bitvale

对于 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)
}

正是我想要的。
X
Xieyi

有时 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());
            }
        }
    });

这是在 Android 5 上对我有用的唯一解决方案
Q
Qantas 94 Heavy

showSoftInput 根本不适合我。

我想我需要设置输入模式:(在清单中的 Activity 组件中)

android:windowSoftInputMode="stateVisible" 

M
Mubashar

要隐藏键盘,请使用这个:

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

并显示键盘:

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

对于 DialogFragment,您可以在覆盖的 onStart() 中调用它,并且可以使用 getDialog().getWindow() 作为 getActivity().getWindow() 的替代。
A
Arish Khan

对于片段,确保其工作:

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

A
Alex Burdusel

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()

M
Marvin Pinto

信不信由你,当我发现活动动画可以禁用软键盘时,我的软键盘问题得到了解决。当您使用

i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);

overridePendingTransition(0, 0);

它可以隐藏软键盘并且没有办法显示它。


n
n0sferat0k

我在各种不同的情况下遇到了同样的问题,我发现的解决方案在某些情况下有效,但在其他情况下无效,所以这里有一个组合解决方案,适用于我发现的大多数情况:

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

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

M
Mike

我在这里结合了所有内容,对我来说它有效:

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

M
Massimiliano Kraus

它对我有用。您也可以尝试使用它来显示键盘:

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

W
Waldmann

只需在 EditText 视图中添加这一行:

android:isScrollContainer="true"

和 TADA - 键盘开始自动出现!

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

正如 user3392439 在这里已经提到的那样,键盘在焦点上的出现与 XML 文件中滚动组件的存在莫名其妙地联系在一起。

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

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

如果没有滚动 - 那么您需要单击 EditText 以使键盘出现。


这很奇怪,但它确实有效 - 我试图从点击处理程序中requesFocus(),这是除了显式 showSoftInput SHOW_FORCED 之外的唯一方法
天哪,谢谢伙计。不知道它为什么会起作用,但我已经在来自不同制造商的 8 台设备上对其进行了测试,并且每次都能正常工作!
谢谢@Waldmann,只有你的回答完美!
不为我工作
J
Jongz Puangput

代码片段。 . .

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

M
Massimiliano Kraus

在您的清单中:

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

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

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

P
Prakash Gavade

只需在清单文件中添加 android:windowSoftInputMode="stateHidden" ...


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

toggleSoftInput 已弃用。
S
Satyajit

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

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

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


B
Bartosz Bilicki

上面给出的所有解决方案(如果您在活动中进行单个编辑,则附加到 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);         
    }       
};

我观察到 onFocusChange 是针对具有 hasFocus=true (显示键盘)的 tvX 触发的,但随后针对具有 hasFocus=true (隐藏键盘)的 tvY 触发。最后,没有可见的键盘。

如果“如果 EditText 文本有焦点则显示键盘”一般解决方案应该有正确的语句


V
Vikas

在 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 是什么?这是这里最重要的一点。
T
Thành Thỏ

正如我在官方文档上阅读的那样,我认为这是最好的答案,只需将 View 传递给 EditText 等参数,但 showSoftKeyboard 似乎不适用于横向

private fun showSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
    }
}

private fun closeSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

J
Jamil Hasnine Tamim

对于科特林:

val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

fun showKeyboard() {
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
    }

fun hideKeyboard() {
        imm.hideSoftInputFromWindow(phoneNoInputTxt.windowToken, 0);
    }

然后只需调用你想要的!


这个答案是不完整的。 InputMethodManager 和 IBinder 引用无法解析。
@MarkLapasa 再次检查我的答案,希望对您有所帮助。谢谢。
S
Steve Kamau

这是我从 Square 获得的更可靠的解决方案:

fun View.focusAndShowKeyboard() { /** * 当窗口已经有焦点时调用。 */ fun View.showTheKeyboardNow() { if (isFocused) { post { // 我们仍然发布调用,以防我们收到窗口焦点通知 // 但 InputMethodManager 尚未正确设置。 val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) } } } requestFocus() if (hasWindowFocus()) { // 无需等待窗口获得焦点。 showTheKeyboardNow() } else { // 我们需要等到窗口获得焦点。 viewTreeObserver.addOnWindowFocusChangeListener( object : ViewTreeObserver.OnWindowFocusChangeListener { override fun onWindowFocusChanged(hasFocus: Boolean) { // 此通知将在 InputMethodManager 设置之前到达。 if (hasFocus) { this@focusAndShowKeyboard.showTheKeyboardNow() // 这很重要完成后删除此侦听器。viewTreeObserver.removeOnWindowFocusChangeListener(this) } } }) } }

来自 here 的代码积分。


使用观察者似乎是处理焦点延迟的更明智的方法,但我无法让它工作......
删除 onWindowFocusChanged 中的 if 语句后对我有用。谢谢