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?

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

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

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"

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

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

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

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())).


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

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>

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

}

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

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)

0

Po prostu dodaj tę linię w swoim kodzie:

getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

0

W Kotlinie:

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

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);
   }
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.