Android显示软键与showSoftInput无法正常工作?

时间:2011-04-01 23:59:42

标签: android show android-softkeyboard android-input-method

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

我的代码不起作用?!

我在清单中尝试了各种“状态”设置,并在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_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello"
        />
    <EditText
        android:id="@+id/edit_sample_text"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        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);
    }
}

14 个答案:

答案 0 :(得分:32)

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

第一种方法

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

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

android:windowSoftInputMode="stateVisible"

答案 1 :(得分:19)

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

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

imm.toggleSoftInput(0, 0);

以下是我的问题: android - show soft keyboard on demand

答案 2 :(得分:18)

这适用于带硬键盘的手机:

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

答案 3 :(得分:16)

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

答案 4 :(得分:8)

这个答案可能很晚,但对我来说非常适合。也许它有助于某人:)

average_...

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

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

答案 5 :(得分:3)

以下为我工作:

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

答案 6 :(得分:2)

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

问题:

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

解决方案:

我使用以下课程。这将持续每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);
    }
}

要使用此功能,只需创建此类的实例即可。将它传递给父活动和targetView,后者将具有键盘输入和焦点。然后使用Handler发布实例。

答案 7 :(得分:1)

我的代码中有切换但没有postDelayed。我曾经尝试过postDelayed for showSoftInput但没有成功,我已经尝试了你建议的解决方案。在我决定增加延迟时间之前,我打算将它作为另一个失败的潜在解决方案丢弃。它适用于我一直到200毫秒,此时它不起作用,至少不在物理电话上。因此,在你糟糕的Android开发人员抛弃这个答案之前,尝试增加延迟以获得成功的解决方案。为较旧的较慢的手机添加一些可能是值得的。谢谢堆,正在努力工作几个小时。

答案 8 :(得分:0)

这对我有用:

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

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

如果要在片段中显示软键盘,则需要等到创建活动后再调用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);
        }
    }

}

答案 11 :(得分:0)

这是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());

答案 12 :(得分:0)

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

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

inputMethodManager.showSoftInput(kbdInput, InputMethodManager.SHOW_IMPLICIT);

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

<EditText
        android:id="@+id/kb_input"
        android:layout_width="0dp"
        android:layout_height="0dp"
      />

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

我的背景是黑色的,所以当 EditText 现在可见时,它在黑色背景上看起来不可见。

答案 13 :(得分:0)

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