¿Cómo ocultar el teclado virtual del interior de un fragmento?

83

Tengo un FragmentActivityuso de ViewPagerpara servir varios fragmentos. Cada uno tiene ListFragmentel siguiente diseño:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="8dp">
        <ListView android:id="@id/android:list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <EditText android:id="@+id/entertext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

Al iniciar la actividad, aparece el teclado en pantalla. Para remediar esto, hice lo siguiente dentro del fragmento:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //Save the container view so we can access the window token
    viewContainer = container;
    //get the input method manager service
    imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    . . .
}

@Override
public void onStart() {
    super.onStart();

    //Hide the soft keyboard
    imm.hideSoftInputFromWindow(viewContainer.getWindowToken(), 0);
}

Guardo el ViewGroup containerparámetro entrante de onCreateViewcomo una forma de acceder al token de ventana para la actividad principal. Esto se ejecuta sin errores, pero el teclado no se oculta de la llamada a hideSoftInputFromWindowin onStart.

Originalmente, intenté usar el diseño inflado en lugar de container, es decir:

imm.hideSoftInputFromWindow(myInflatedLayout.getWindowToken(), 0);

pero esto arrojó un NullPointerException, presumiblemente porque el fragmento en sí no es una actividad y no tiene un token de ventana único.

¿Hay alguna forma de ocultar el teclado virtual desde dentro de un fragmento, o debería crear un método en el FragmentActivityy llamarlo desde dentro del fragmento?

WilHall
fuente

Respuestas:

180

Siempre que su Fragmento cree una Vista, puede usar el IBinder (token de ventana) de esa vista después de que se haya adjuntado. Por ejemplo, puede anular onActivityCreated en su Fragmento:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
Ian G. Clifton
fuente
9
Agregué esto a mi proyecto. pero cuando hago clic en otra pestaña, se bloquea.
andro-girl
4
Para aquellos que están haciendo esto y obtienen un bloqueo con una NullPointerException, simplemente use el InputMethodManager dentro de su fragmento del método onCreateView. Al hacerlo, tendrá su vista y podrá cambiar la última línea usando la vista que ha inflado a imm.hideSoftInputFromWindow (view.getWindowToken (), 0);
Aurasphere
84

Nada más que la siguiente línea de código funcionó para mí:

getActivity().getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Shajeel Afzal
fuente
1
SOFT_INPUT_STATE_HIDDENtambién funcionó para mí, aunque no sé cuál es la diferencia entre eso y 'SOFT_INPUT_STATE_ALWAYS_HIDDEN'.
hBrent
2
La primera respuesta no funcionó, esta funcionó. Gracias
moujib
1
Gracias por ahorrarme tiempo, amigo.
Harish Reddy
Mi situación es que estoy usando fragment / TabView. La primera pestaña tiene "Consejos" en un TextView. La segunda pestaña tiene una actividad donde tengo EditText (s) con "editText1.setShowSoftInputOnFocus (false);" conjunto de comandos y mi propio teclado personalizado. Cuando pongo la aplicación en segundo plano y luego la vuelvo a mostrar, aparece el teclado en pantalla no deseado. La configuración del comando anterior en el método onStart Life Cycle Override detiene esto. Gracias @Shajeel Afzal
Forever a CS Student
21

Si agrega el siguiente atributo a la definición del manifiesto de su actividad, evitará por completo que el teclado salte cuando se abra su actividad. Ojalá esto ayude:

(Agregue a la definición de manifiesto de su actividad):

android:windowSoftInputMode="stateHidden"
Eric Schlenz
fuente
Gracias, esto es lo que terminé haciendo. Sin embargo, todavía me gustaría saber cómo usar el Administrador de métodos de entrada para mostrar / ocultar el teclado, porque es posible que necesite usarlo en algún momento después de que comience la actividad.
WilHall
12
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_my, container,
                false);
        someClass.onCreate(rootView);
        return rootView;
    }

Mantener una instancia de mi vista raíz en mi clase

View view;

public void onCreate(View rootView) {
    view = rootView;

Usa la vista para ocultar el teclado

 public void removePhoneKeypad() {
    InputMethodManager inputManager = (InputMethodManager) view
            .getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);

    IBinder binder = view.getWindowToken();
    inputManager.hideSoftInputFromWindow(binder,
            InputMethodManager.HIDE_NOT_ALWAYS);
}
Aplicaciones móviles
fuente
Usé esto pero usé getView () de mi fragmento en lugar de mantener una instancia de mi vista.
MrEngineer13
OnCreate es una clase fuera del Fragmento, así que le paso el rootView para poder usarlo para eliminar el phoneKeyPad en esta clase. Supongo que lo querían desde dentro del Fragmento, no una clase en el Fragmento.
Aplicaciones móviles
10

Sin DialogFragmentembargo, con la excepción de que el foco del incrustado Dialogdebe estar oculto, solo el primero EditTextdentroDialog

this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
macio.Jun
fuente
5
Esta es la única forma de ocultar el teclado, si tiene DialogFragment.
Matjaz Kristl
donde escribir esto
Mstack
@Mstack, funciona con el método onActivityCreated (). override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
Sami Issa
7

Este código funciona para fragmentos:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Keshav Gera
fuente
4

Utilice este método estático, desde cualquier lugar (Actividad / Fragmento) que desee.

public static void hideKeyboard(Activity activity) {
    try{
        InputMethodManager inputManager = (InputMethodManager) activity
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        View currentFocusedView = activity.getCurrentFocus();
        if (currentFocusedView != null) {
            inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

Si desea utilizar para fragmento, simplemente llame hideKeyboard(((Activity) getActivity())).

Nazmus Saadat
fuente
3

esto funcionará en mi caso cuando en las pestañas cambie de un fragmento a otro fragmentos

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        try {
            InputMethodManager mImm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            mImm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
            mImm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
        } catch (Exception e) {
            Log.e(TAG, "setUserVisibleHint: ", e);
        }
    }
}
Meerz
fuente
Si tiene un fragmento de pestaña y desea ocultar el teclado solo para algunas pestañas, use esto.
Ronny Sulistio
1

Nada de esto funcionó en API27. Tuve que agregar esto en el contenedor del diseño, para mí era un ConstraintLayout:

<android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:focusedByDefault="true">

//Your layout

</android.support.constraint.ConstraintLayout>
hiddeneyes02
fuente
no funciona en api <26, pero esto (dentro de la clase de fragmento) @Override public void onResume () {super.onResume (); getView (). setFocusable (verdadero); getView (). setFocusableInTouchMode (verdadero); getView (). requestFocus (); }
Darko
1

Esto funcionó para mí en la clase de Kotlin

fun hideKeyboard(activity: Activity) {
    try {
        val inputManager = activity
            .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        val currentFocusedView = activity.currentFocus
        if (currentFocusedView != null) {
            inputManager.hideSoftInputFromWindow(currentFocusedView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }

}
Aprende rápido
fuente
1

Use este código en cualquier escucha de botón de fragmento:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
Stan Peng
fuente
Funciona, pero debe verificar si getActivity().getCurrentFocus().getWindowToken()no es nulo, de lo contrario causará un error si no hay un editText enfocado. Vea mi respuesta a continuación
Duc Trung Mai
0

Simplemente agregue esta línea en su código:

getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Buda digital
fuente
0

En Kotlin:

(activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view?.windowToken,0)
timeSmith
fuente
0

Utilizar esta:

Button loginBtn = view.findViewById(R.id.loginBtn);
loginBtn.setOnClickListener(new View.OnClickListener() {
   public void onClick(View v) {
      InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
      imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
   }
});
Duc Trung Mai
fuente