Как скрыть мягкую клавиатуру изнутри фрагмента?


84

Я FragmentActivityиспользую ViewPagerдля обслуживания нескольких фрагментов. Каждый из них имеет ListFragmentследующий макет:

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

При запуске занятия отображается программная клавиатура. Чтобы исправить это, я сделал внутри фрагмента следующее:

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

Я сохраняю входящий ViewGroup containerпараметр from onCreateViewкак способ доступа к токену окна для основного действия. Это выполняется без ошибок, но клавиатура не получает скрыта от вызова hideSoftInputFromWindowв onStart.

Изначально я пробовал использовать раздутый макет вместо container, то есть:

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

но это вызвало ошибку NullPointerException, предположительно потому, что сам фрагмент не является действием и не имеет уникального токена окна?

Есть ли способ скрыть мягкую клавиатуру из фрагмента, или я должен создать метод в FragmentActivityи вызвать его из фрагмента?

Ответы:


181

Пока ваш фрагмент создает представление, вы можете использовать IBinder (токен окна) из этого представления после его присоединения. Например, вы можете переопределить onActivityCreated в своем фрагменте:

@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
Я добавил это в свой проект, но когда я нажимаю на другую вкладку, происходит сбой.
andro-girl

4
Для тех, кто делает это и получает сбой с исключением NullPointerException, просто используйте InputMethodManager внутри метода onCreateView вашего фрагмента. При этом у вас будет свое представление, и вы можете изменить последнюю строку, используя представление, которое вы расширили до imm.hideSoftInputFromWindow (view.getWindowToken (), 0);
Aurasphere 08

84

У меня ничего не сработало, кроме следующей строчки кода:

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

1
SOFT_INPUT_STATE_HIDDENтакже работал у меня, хотя я не знаю, в чем разница между этим и SOFT_INPUT_STATE_ALWAYS_HIDDEN.
hBrent

2
Первый ответ не сработал, этот сработал. Спасибо
moujib 02

1
Спасибо, что сэкономил время, приятель.
Harish Reddy

Моя ситуация: я использую фрагмент / TabView. На первой вкладке есть «Советы» в TextView. На второй вкладке есть действие, в котором у меня есть EditText (s) с "editText1.setShowSoftInputOnFocus (false);" набор команд и моя собственная клавиатура. Когда я помещаю приложение в фоновый режим, а затем возвращаю приложение в поле зрения, всплывала нежелательная программная клавиатура. Установка указанной выше команды в методе onStart Life Cycle Override останавливает это. Спасибо @Shajeel Afzal
Forever a CS Student

21

Если вы добавите следующий атрибут в определение манифеста вашего действия, он полностью подавит всплытие клавиатуры при открытии вашего действия. Надеюсь, это поможет:

(Добавьте в определение манифеста вашей деятельности):

android:windowSoftInputMode="stateHidden"

Спасибо, это то, чем я закончил. Однако я все же хотел бы знать, как использовать диспетчер методов ввода, чтобы показать / скрыть клавиатуру, потому что мне может потребоваться использовать его через некоторое время после начала действия.
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;
    }

Сохраните экземпляр моего корневого представления в моем классе

View view;

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

Используйте вид, чтобы скрыть клавиатуру

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

    IBinder binder = view.getWindowToken();
    inputManager.hideSoftInputFromWindow(binder,
            InputMethodManager.HIDE_NOT_ALWAYS);
}

Я использовал это, но я использовал getView () из моего фрагмента вместо сохранения экземпляра моего представления.
MrEngineer13

OnCreate - это класс вне фрагмента, поэтому я передаю ему rootView, чтобы иметь возможность использовать его для удаления phoneKeyPad в этом классе. Я полагаю, они хотели, чтобы это было внутри Фрагмента, а не класса во Фрагменте.
Мобильные приложения

11

DialogFragmentОднако, за исключением , фокус встроенного Dialogдолжен быть скрыт, а не только первый EditTextво встроенномDialog

this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

5
Это единственный способ скрыть клавиатуру, если у вас есть DialogFragment.
Matjaz Kristl

где это написать?
Mstack

@Mstack, работает с методом onActivityCreated (). override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
Сами Исса,

7

Этот код работает для фрагментов:

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

4

Используйте этот статический метод из любого места (Activity / 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();
    }
}

Если вы хотите использовать для фрагмента, просто позвоните hideKeyboard(((Activity) getActivity())).


3

это будет работать в моем случае, когда во вкладках я переключаюсь с одного фрагмента на другой фрагменты

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

если у вас есть фрагмент вкладки и вы хотите скрыть клавиатуру только для нескольких вкладок, используйте это.
Ронни Сулистио

1

Ничего из этого не работало с API27. Мне пришлось добавить это в контейнер макета, для меня это был 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>

он не работает с api <26, но это работает (внутри класса фрагмента) @Override public void onResume () {super.onResume (); getView (). setFocusable (правда); getView (). setFocusableInTouchMode (правда); getView (). requestFocus (); }
Дарко

1

Это сработало для меня в классе 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

Используйте этот код в любом прослушивателе кнопки фрагмента:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);

Работает, но вы должны проверить, не getActivity().getCurrentFocus().getWindowToken()является ли он нулевым, иначе это вызовет ошибку, если нет сфокусированного editText. См. Мой ответ ниже
Duc Trung Mai

1

Код Котлина

val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)

0

Просто добавьте эту строку в свой код:

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

0

В Котлине:

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

0

Использовать этот:

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);
   }
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.