Jak ukryć miękką klawiaturę przed fragmentem?

84

Mam do FragmentActivitypodania ViewPagerkilku fragmentów. Każdy ma ListFragmentnastępujący układ:

<?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>

Podczas rozpoczynania działania wyświetlana jest klawiatura programowa. Aby temu zaradzić, wewnątrz fragmentu wykonałem następujące czynności:

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

Zapisuję ViewGroup containerparametr przychodzący z onCreateViewjako sposób na dostęp do tokena okna dla głównej czynności. To działa bez błędu, ale klawiatura nie zostanie ukryte przed wywołaniem hideSoftInputFromWindoww onStart.

Pierwotnie próbowałem użyć zawyżonego układu zamiast container, tj .:

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

ale to wyrzuciło NullPointerException, prawdopodobnie dlatego, że sam fragment nie jest działaniem i nie ma unikalnego tokenu okna?

Czy istnieje sposób na ukrycie klawiatury programowej przed fragmentem, czy też powinienem utworzyć metodę w FragmentActivityi wywołać ją z wnętrza fragmentu?

WilHall
źródło

Odpowiedzi:

181

Dopóki Twój Fragment tworzy Widok, możesz użyć IBinder (tokena okna) z tego widoku po jego dołączeniu. Na przykład możesz zastąpić onActivityCreated w swoim fragmencie:

@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
źródło
9
Dodałem to do mojego projektu, ale kiedy klikam inną kartę, dochodzi do awarii.
andro-girl
4
Dla tych, którzy robią to i mają awarię z NullPointerException, po prostu użyj InputMethodManager wewnątrz metody onCreateView fragmentu. Robiąc to, będziesz miał swój widok i możesz zmienić ostatnią linię za pomocą widoku, który nadałeś, na imm.hideSoftInputFromWindow (view.getWindowToken (), 0);
Aurasphere
84

Nie działało dla mnie nic poza następującym wierszem kodu:

getActivity().getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Shajeel Afzal
źródło
1
SOFT_INPUT_STATE_HIDDENteż działało dla mnie, chociaż nie wiem, jaka jest różnica między tym a `SOFT_INPUT_STATE_ALWAYS_HIDDEN '.
hBrent
2
Pierwsza odpowiedź nie zadziałała, ta załatwiła sprawę. Dzięki
moujib
1
Dzięki za zaoszczędzenie czasu, stary.
Harish Reddy
Moja sytuacja jest taka, że ​​używam fragmentu / TabView. Pierwsza karta zawiera „Porady” w TextView. Druga karta ma działanie, w którym mam EditText (y) z "editText1.setShowSoftInputOnFocus (false);" zestaw poleceń i moja własna klawiatura. Kiedy umieściłem aplikację w tle, a następnie przywróciłem ją do widoku, niechciana klawiatura miękka wyskakuje. Ustawienie powyższego polecenia w metodzie onStart Life Cycle Override zatrzymuje to. Dzięki @Shajeel Afzal
Forever a CS Student
21

Jeśli dodasz następujący atrybut do definicji manifestu działania, całkowicie wyeliminuje on wyskakiwanie klawiatury po otwarciu działania. Mam nadzieję, że to pomoże:

(Dodaj do definicji manifestu swojej aktywności):

android:windowSoftInputMode="stateHidden"
Eric Schlenz
źródło
Dzięki, właśnie to zrobiłem. Jednak nadal chciałbym wiedzieć, jak używać Menedżera metody wprowadzania, aby pokazać / ukryć klawiaturę, ponieważ może być konieczne użycie go jakiś czas po rozpoczęciu ćwiczenia.
WilHall
13
    @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;
    }

Zachowaj instancję mojego widoku głównego w mojej klasie

View view;

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

Użyj widoku, aby ukryć klawiaturę

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

    IBinder binder = view.getWindowToken();
    inputManager.hideSoftInputFromWindow(binder,
            InputMethodManager.HIDE_NOT_ALWAYS);
}
Aplikacje mobilne
źródło
Użyłem tego, ale użyłem getView () z mojego fragmentu zamiast zachować wystąpienie mojego widoku.
MrEngineer13
OnCreate jest klasą poza fragmentem, więc przekazuję mu rootView, aby móc go użyć do usunięcia phoneKeyPad z tej klasy. Przypuszczam, że chcieli tego z wnętrza Fragmentu, a nie klasy we fragmencie.
Aplikacje mobilne
11

Wyjątkiem jest DialogFragmentjednak fakt, że fokus elementu osadzonego Dialogmusi być ukryty, a nie tylko pierwszy EditTextelement osadzonyDialog

this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
macio.Jun
źródło
5
Jest to jedyny sposób na ukrycie klawiatury, jeśli masz DialogFragment.
Matjaz Kristl,
gdzie to napisać?
Mstack
@Mstack, działa na metodzie onActivityCreated (). override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
Sami Issa
7

Ten kod działa dla fragmentów:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Keshav Gera
źródło
4

Użyj tej statycznej metody z dowolnego miejsca (aktywność / fragment).

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

Jeśli chcesz użyć fragmentu, po prostu zadzwoń hideKeyboard(((Activity) getActivity())).

Nazmus Saadat
źródło
3

tak będzie w moim przypadku, gdy w zakładkach przełączam się z jednego fragmentu na inny

@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
źródło
jeśli masz fragment zakładki i chcesz ukryć klawiaturę tylko dla kilku zakładek, użyj tego.
Ronny Sulistio
1

Nic z tego nie działało na API27. Musiałem dodać to w kontenerze układu, dla mnie był to 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>
ukryte oczy02
źródło
nie działa na api <26, ale działa (wewnątrz klasy fragmentu) @Override public void onResume () {super.onResume (); getView (). setFocusable (true); getView (). setFocusableInTouchMode (true); getView (). requestFocus (); }
Darko
1

To zadziałało dla mnie w klasie 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()
    }

}
Szybki uczeń
źródło
1

Użyj tego kodu w dowolnym odbiorniku przycisków fragmentów:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
Stan Peng
źródło
Działa, ale musisz sprawdzić, czy getActivity().getCurrentFocus().getWindowToken()nie jest null, w przeciwnym razie spowoduje to błąd, jeśli nie ma skupionego tekstu editText. Zobacz moją odpowiedź poniżej
Duc Trung Mai,
1

Kod Kotlin

val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)
RonaldPaguay
źródło
0

Po prostu dodaj tę linię w swoim kodzie:

getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Cyfrowy Budda
źródło
0

W Kotlinie:

(activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view?.windowToken,0)
timeSmith
źródło
0

Użyj tego:

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
źródło