如何在Android Fragment中完美显示软键盘?

12
我在一个Activity的Fragment中有一个EditText。
我的Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/login_bg">
    ...

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    ...

</RelativeLayout>

我的 AndroidManifest.xml 中的 Activity 配置:

    <activity
        android:name="com.demo.LoginActivity"
        android:configChanges="orientation|keyboardHidden"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:theme="@style/activityTheme" />

我在Activity中用来启动Fragment的代码:

private void startFragment(BaseFragment fragment, String tag) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.addToBackStack(tag);
    fragmentTransaction.commitAllowingStateLoss();
}

我的 Fragment 布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_background_color_white"
    android:orientation="vertical"
    android:clickable="true"
    android:paddingLeft="@dimen/email_common_padding_horizontal"
    android:paddingRight="@dimen/email_common_padding_horizontal">

    ...

    <com.example.widget.LineEditView
        android:id="@+id/login_email_input"
        style="@style/BaseEditText.LoginEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="true"
    />

    ...

</LinearLayout>

我的自定义小部件LineEditView是一个继承RelativeLayout的子类,并且它有布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:gravity="start|center_vertical"
        android:background="@android:color/transparent"
        android:textColor="@color/common_text_color_black"
        android:maxLines="1"
        android:textCursorDrawable="@drawable/common_cursor_background_orange"
        android:textSize="@dimen/email_fields_text_size"
        android:paddingBottom="@dimen/email_fields_text_padding_bottom"/>

    <View
        android:id="@+id/underline"
        android:layout_below="@id/edit"
        android:layout_width="match_parent"
        android:layout_height="2px"/>
</RelativeLayout> 

我想根据EditText的inputType属性显示软键盘,并且可以轻松地隐藏。

我尝试过但不起作用或不完美的方法:

1.根据Show keyboard for edittext when fragment starts可以显示软键盘,但无法轻松隐藏(有时甚至无法隐藏),而且它显示的键盘不符合EditText的inputType属性。

2.我在我的Fragment中添加了以下代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container) {
    mEditText = (EditText) rootView.findViewById(R.id.edit);
    mEditText.requestFocus();
    mEditText.setFocusable(true);
}

@Override
public void onResume() {
    mEditText.postDelayed(mShowSoftInputRunnable, 400);
    super.onResume();
}

private Runnable mShowSoftInputRunnable = new Runnable() {
    @Override
    public void run() {
        FragmentActivity activity = getActivity();
        if (activity == null)
            return;

        InputMethodManager input = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        input.showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT);
    }
};

然而在我的 Fragment 中无法显示软键盘。

我不能将 EditText 放入 Activity,因为这需要重新构建很多代码。

有人有解决这些问题的想法吗?

2个回答

44

这是我在Fragment中使用的代码,非常有效

public static void hideKeyboard(Context context) {
    try {
        ((Activity) context).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        if ((((Activity) context).getCurrentFocus() != null) && (((Activity) context).getCurrentFocus().getWindowToken() != null)) {
            ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(((Activity) context).getCurrentFocus().getWindowToken(), 0);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void showKeyboard(Context context) {
    ((InputMethodManager) (context).getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}

1
谢谢,你的答案帮了我很多。 - Waylent
1
非常感谢。这个完美地运作了!尝试了所有其他的东西!没有像这样好用! - adnaan.zohran
你们俩都非常受欢迎。这段代码是我用过的最好的代码,用于在Android中显示或隐藏软键盘。 - apmartin1991

8

hideSoftKeyboard

在Fragment中,需要在想要隐藏键盘时调用此函数。

hideSoftKeyboard(getActivity());

调用函数

  private void hideSoftKeyboard(Activity activity)
{
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

showSoftKeyboard

调用此函数可以在片段中显示键盘并传递编辑框参数。

 EditText edittext=(EditText) findViewById(R.id.edittext);
 showSoftKeyboard(edittext);

调用这个函数。
 public void showSoftKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager)getActivity(). getSystemService(Activity.INPUT_METHOD_SERVICE);
    view.requestFocus();
    inputMethodManager.showSoftInput(view, 0);
}

谢谢你的帮助。但是你的showSoftKeyboard方法可能需要在view.postDelayed()中执行,否则它可能无法工作。而你的hideSoftKeyboard方法可能需要添加((Activity) context).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); - Waylent
谢谢你!你救了我! - Cypher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接