带有 showSoftInput 的 Android 显示软键盘不起作用?

Posted

技术标签:

【中文标题】带有 showSoftInput 的 Android 显示软键盘不起作用?【英文标题】:Android show softkeyboard with showSoftInput is not working? 【发布时间】:2011-07-28 01:34:01 【问题描述】:

我创建了一个简单的应用程序来测试以下功能。当我的活动启动时,它需要在软键盘打开的情况下启动。

我的代码不起作用?!

我尝试了清单中的各种“状态”设置以及 InputMethodManager (imm) 代码中的不同标志。

我已将设置包含在 androidManifest.xml 中,并在唯一活动的 onCreate 中显式调用。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.mycompany.android.studyIme"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".StudyImeActivity"
                  android:label="@string/app_name" 
                  android:windowSoftInputMode="stateAlwaysVisible">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

...主布局(main.xml)...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_
    >
    <TextView  
        android:layout_ 
        android:layout_ 
        android:text="@string/hello"
        />
    <EditText
        android:id="@+id/edit_sample_text"
        android:layout_ 
        android:layout_
        android:hint="@string/hello"
        android:inputType="textShortMessage"
    />
</LinearLayout>

...和代码...

public class StudyImeActivity extends Activity 
    private EditText mEditTextStudy;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mEditTextStudy = (EditText) findViewById(R.id.edit_study);
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(mEditTextStudy, InputMethodManager.SHOW_FORCED);
    

【问题讨论】:

嗯 ...我刚刚在我的 Sprint LG Optimus 手机上尝试了这个,只有默认的“HelloWorld”活动(即不包括 SHOW_FORCED 代码),它按预期工作。该功能是否可能取决于设备(已安装操作系统)?回家后,我会在其他设备(HTC、G2 和 MyTouch)上再次测试。 请在此处查看我的回复,我已经尝试了下面提到的所有技术,但都奏效了:***.com/a/37529370/3900270 【参考方案1】:

当活动启动时,键盘似乎最初显示但被其他东西隐藏,因为以下工作(但实际上是一个肮脏的解决方法):

第一种方法

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
editText.postDelayed(new Runnable()

    @Override
    public void run()
    
        editText.requestFocus();
        imm.showSoftInput(editText, 0);
    
, 100);

第二种方法

在 onCreate 中在活动创建时启动它

new Handler().postDelayed(new Runnable() 
    @Override
    public void run() 
    
    //  InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    //    inputMethodManager.toggleSoftInputFromWindow(EnterYourViewHere.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);

        if (inputMethodManager != null)
        
            inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
         
    
, 200);

第三种方法 将给定代码添加到清单中的活动标签。它会在启动时显示键盘,并将第一个焦点设置为您想要的视图。

android:windowSoftInputMode="stateVisible"

【讨论】:

我也有同样的问题。立即调用showSoftInput() 没有可见结果,但延迟发布它会导致键盘正确显示。我最初像你一样认为它正在被展示,然后很快被其他东西隐藏起来。经过一番挖掘,我发现我可以传入ResultReceiver 并记录结果。当我延迟发布showSoftInput() 时,返回给我的接收者的结果代码是RESULT_SHOWN。当我不使用延迟时,我的接收器根本不会被调用。现在我怀疑它不是被隐藏了,而是出于某种原因根本没有显示出来。 谢谢伙计。在修复第一次启动对话框片段(带有 EditText)时键盘不显示的问题时使用了第一种方法。 postDelayedpost 的另一个投票支持 - 可能还有其他一些默认的隐藏功能导致键盘首先被隐藏。显示和隐藏键盘是现存最严重的 API。 您的第一种方法在以编程方式切换布局和打开键盘时效果很好。似乎某些其他进程正在阻止 showSoftInput() 正常运行。【参考方案2】:

嘿,我希望您仍在寻找我在测试我的代码时找到的答案。这是代码:

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

imm.toggleSoftInput(0, 0);

我的问题得到了回答: android - show soft keyboard on demand

【讨论】:

暴力救援! (我们有一个内部应用程序,只支持一个平板电脑,所以我们的标准操作程序是使用那个软键盘,所以我们没有理由让用户等待)【参考方案3】:

这在带有硬键盘的手机上对我有用:

editText1.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
          imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

【讨论】:

太好了,我错过了 requestFocus(),它第一次停止显示键盘。【参考方案4】:

这是非常微妙的,它是犯罪。这适用于具有硬滑出式键盘的手机。带有硬键盘的电话不会随此呼叫自动打开。我的 LG 和旧的 Nexus One 没有键盘 - 因此,当活动启动时软键盘会打开(这就是我想要的),但具有滑出式键盘的 MyTouch 和 HTC G2 手机不会打开软键盘键盘,直到我在硬键盘关闭的情况下触摸编辑字段。

【讨论】:

注意:我对 EditText 和 InputMethodManager 做了很多试验,试图在设备有硬键盘但没有成功时强制打开软键盘。 对于在 Visual Studio 中进行 Xamarin 开发的任何人,您可以在 AVD 管理器中编辑您的 AVD,并且有一个标记为“存在硬件键盘”的设置。取消选中此项将允许显示软输入。 @arbitur -- 你可以放松一下。这就像一百年前的谷歌时代。 (您是否知道有人甚至制造了滑出式硬键盘——哈哈)。那时,我是唯一对问题和解决方案感兴趣的人,所以我努力做到完整。【参考方案5】:

这个答案可能迟了,但它对我来说非常有效。也许它可以帮助某人:)

public void showSoftKeyboard(View view) 
    if (view.requestFocus()) 
        InputMethodManager imm = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);
        boolean isShowing = imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
        if (!isShowing)
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    

取决于你的需要,你可以使用其他标志

InputMethodManager.SHOW_FORCED
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

【讨论】:

在显示键盘之前请求焦点效果很好??(我有相反的方式)【参考方案6】:

显示软键盘是个大问题。我进行了很多搜索以得出最终结论。感谢这个答案提供了许多线索:https://***.com/a/16882749/5903344

问题:

通常我们在初始化视图后立即调用 showSoftInput。在Activities中,这主要是在onCreate中,在Fragments onCreateView中。为了显示键盘,IMM 需要激活 focsedView。这可以使用 IMM 的 isActive(view) 方法进行检查。如果我们在创建视图时调用 showSoftInput,则该视图很可能不会对 IMM 处于活动状态。这就是为什么有时延迟 50-100 毫秒的 showSoftInput 很有用的原因。但是,这仍然不能保证 100 毫秒后视图将变为活动状态。所以在我看来,这又是一个 hack。

解决方案:

我使用以下课程。这将每 100 毫秒运行一次,直到成功显示键盘。它在每次迭代中执行各种检查。有些检查可以停止可运行,有些会在 100 毫秒后发布。

public class KeyboardRunnable extends Runnable

    // ----------------------- Constants ----------------------- //
    private static final String TAG = "KEYBOARD_RUNNABLE";

    // Runnable Interval
    private static final int INTERVAL_MS = 100;

    // ----------------------- Classes ---------------------------//
    // ----------------------- Interfaces ----------------------- //
    // ----------------------- Globals ----------------------- //
    private Activity parentActivity = null;
    private View targetView = null;

    // ----------------------- Constructor ----------------------- //
    public KeyboardRunnable(Activity parentActivity, View targetView)
    
        this.parentActivity = parentActivity;
        this.targetView = targetView;
    

    // ----------------------- Overrides ----------------------- //
    @Override
    public void run()
    
        // Validate Params
        if ((parentActivity == null) || (targetView == null))
        
            Dbg.error(TAG, "Invalid Params");
            return;
        

        // Get Input Method Manager
        InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);

        // Check view is focusable
        if (!(targetView.isFocusable() && targetView.isFocusableInTouchMode()))
        
            Dbg.error(TAG, "Non focusable view");
            return;
        
        // Try focusing
        else if (!targetView.requestFocus())
        
            Dbg.error(TAG, "Cannot focus on view");
            Post();
        
        // Check if Imm is active with this view
        else if (!imm.isActive(targetView))
        
            Dbg.error(TAG, "IMM is not active");
            Post();
        
        // Show Keyboard
       else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT))
        
            Dbg.error(TAG, "Unable to show keyboard");
            Post();
        
    

    // ----------------------- Public APIs ----------------------- //
    public static void Hide(Activity parentActivity)
    
        if (parentActivity != null)
        
            InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(parentActivity.findViewById(android.R.id.content).getWindowToken(), 0);
        
        else
        
            Dbg.error(TAG, "Invalid params to hide keyboard");
        
    

    // ----------------------- Private APIs ----------------------- //
    protected void Post()
    
        // Post this aftr 100 ms
        handler.postDelayed(this, INTERVAL_MS);
    

要使用它,只需创建这个类的一个实例。将父 Activity 和 targetView 传递给它,之后它们将具有键盘输入和焦点。然后使用 Handler 发布实例。

【讨论】:

【参考方案7】:

以下对我有用:

    mEditTextStudy.requestFocus();
    mEditTextStudy.post(
            new Runnable() 
                @Override
                public void run() 
                    InputMethodManager imm =
                            (InputMethodManager)
                                    getActivity()
                                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) 
                        imm.showSoftInput(mEditTextStudy, SHOW_FORCED);
                    
                
            );

【讨论】:

【参考方案8】:

我的代码中有开关,但没有 postDelayed。我曾为 showSoftInput 尝试过 postDelayed ,但没有成功,此后我尝试了您建议的解决方案。在我决定增加延迟时间之前,我正准备将它作为另一个失败的潜在解决方案丢弃。它对我来说一直有效到 200 毫秒,此时它不起作用,至少在实体手机上不起作用。因此,在您可怜的 android 开发人员放弃这个答案之前,请尝试增加延迟以获得成功的解决方案。为较旧的较慢手机添加一点可能是值得的。非常感谢,已经为此工作了好几个小时。

【讨论】:

【参考方案9】:

Xamarin 开发人员解决方案 (_digit1 == EditText):

        var focussed = _digit1.RequestFocus();
        if (focussed)
        
            Window.SetSoftInputMode(SoftInput.StateAlwaysVisible);
            var imm = (InputMethodManager)GetSystemService(InputMethodService);
            imm.ToggleSoftInput(ShowFlags.Forced, 0);
        

【讨论】:

【参考方案10】:

这是 Siddharth Garg 答案的修改版本。它在 100% 的时间内都有效。

import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

public class SoftInputService implements Runnable 

    private static final String TAG = SoftInputService.class.getSimpleName();

    private static final int INTERVAL_MS = 100;

    private Context context;
    private View targetView;
    private Handler handler;

    public SoftInputService(Context context, View targetView) 
        this.context = context;
        this.targetView = targetView;
        handler = new Handler(Looper.getMainLooper());
    

    @Override
    public void run() 
        if (context == null || targetView == null) 
            return;
        

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

        if (!targetView.isFocusable() || !targetView.isFocusableInTouchMode()) 
            Log.d(TAG,"focusable = " + targetView.isFocusable() + ", focusableInTouchMode = " + targetView.isFocusableInTouchMode());
            return;

         else if (!targetView.requestFocus()) 
            Log.d(TAG,"Cannot focus on view");
            post();

         else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT)) 
            Log.d(TAG,"Unable to show keyboard");
            post();
        
    

    public void show() 
        handler.post(this);
    

    public static void hide(Context context, IBinder windowToekn) 
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(windowToekn, 0);
    

    protected void post() 
        handler.postDelayed(this, INTERVAL_MS);
    

用法:

// To show the soft input
new SoftInputService(context, theEditText).show();
// To hide the soft input
SoftInputService.hide(context, theEditText.getWindowToken());

【讨论】:

【参考方案11】:

类似的问题但不同的解决方案,因此发布以防对其他人有用。

问题不在于我的代码和使用:

inputMethodManager.showSoftInput(kbdInput, InputMethodManager.SHOW_IMPLICIT);

与最近的 sdk 编译相关的问题。我不再能够将上述内容应用于隐藏的字段。似乎您现在必须使您的字段可见并且大于 0 才能显示键盘。我这样做是因为我的应用程序更像是一个使用键盘作为图像输入的游戏。所以我所要做的就是改变:

<EditText
        android:id="@+id/kb_input"
        android:layout_
        android:layout_
      />

<EditText
        android:id="@+id/kb_input"
        android:layout_
        android:layout_
        android:textColor="@color/black"
        android:textColorHighlight="@color/black"
        android:backgroundTint="@color/black"
        android:cursorVisible="false"
      />

我的背景是黑色的,所以虽然 EditText 现在可见,但在黑色背景上看起来不可见。

【讨论】:

我在这个问题上苦苦挣扎了一段时间,终于解决了!【参考方案12】:

这对我有用:

public void requestFocusAndShowSoftInput(View view)
    view.requestFocus();
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);

【讨论】:

【参考方案13】:

如果您尝试在 Fragment 中显示软键盘,则需要等到创建 Activity 后再调用 showSoftInput()。示例代码:

public class SampleFragment extends Fragment 

    private InputMethodManager mImm;
    private TextView mTextView;

    @Override
    public void onAttach(Context context) 
        super.onAttach(context);
        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);
        showSoftKeyboard(mTextView);
    

    /**
     * Request the InputMethodManager show the soft keyboard.  Call this in @link #onActivityCreated(Bundle).
     * @param view the View which would like to receive text input from the soft keyboard
     */
    public void showSoftKeyboard(View view) 
        if (view.requestFocus()) 
            mImm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
        
    


【讨论】:

【参考方案14】:

从清单中删除 android:windowSoftInputMode 解决了我的问题!

【讨论】:

以上是关于带有 showSoftInput 的 Android 显示软键盘不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

无法保存 SharedPreferences 值,而是我得到: D/InputMethodManager: showSoftInput fail

Xamarin Android - 带有图标的条目 - SetCompoundDrawablesWithIntrinsicBounds - TOUCH/Click 事件?

如何在颤动中显示带有提交按钮和隐藏输入字段的html表单

sh 在Androi设备上录制屏幕

如何在带有 Android 5.0 Lollipop 的代码(不是 xml)中以编程方式使用 RippleDrawable?

androi 多线程