如何从片段内隐藏软键盘?

时间:2011-10-29 18:18:11

标签: java android android-fragments android-softkeyboard

我有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的传入onCreateView参数,作为访问主要活动的窗口令牌的方法。这样运行没有错误,但键盘不会在hideSoftInputFromWindow中对onStart的调用中隐藏。

最初,我尝试使用膨胀的布局而不是container,即:

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

但这引起了NullPointerException,大概是因为片段本身不是一个活动而且没有唯一的窗口令牌?

有没有办法在片段中隐藏软键盘,还是应该在FragmentActivity中创建一个方法并从片段中调用它?

18 个答案:

答案 0 :(得分:160)

只要您的Fragment创建了一个View,就可以在附加之后使用该视图中的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);
}

答案 1 :(得分:74)

以下代码行只为我工作:

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

答案 2 :(得分:21)

如果您将以下属性添加到活动的清单定义中,它将完全禁止键盘在您的活动打开时弹出。希望这会有所帮助:

(添加到您的活动的清单定义):

android:windowSoftInputMode="stateHidden"

答案 3 :(得分:12)

<html>
  <body>
    <div class="antoher-element">
      <div id="background">

在我的班级中保留我的根视图实例

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

答案 4 :(得分:9)

DialogFragment的例外情况,必须隐藏嵌入式Dialog的焦点,而只隐藏嵌入式EditText

中的第一个Dialog
this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

答案 5 :(得分:6)

在Fragemnt中使用此代码

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

答案 6 :(得分: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);
        }
    }
}

答案 7 :(得分:2)

在您喜欢的任何位置(活动/片段)使用此静态方法。

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

答案 8 :(得分: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()
    }

}

答案 9 :(得分:1)

在任何片段按钮侦听器中使用此代码:

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

答案 10 :(得分:1)

Kotlin 代码

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

答案 11 :(得分:0)

在片段中对我有用的解决方案:

fun hideKeyboard(){
    val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(view?.windowToken, 0)
}

在一个活动中:

fun hideKeyboard(){
    val inputManager: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    inputManager.hideSoftInputFromWindow(currentFocus?.windowToken, InputMethodManager.SHOW_FORCED)
}

答案 12 :(得分:0)

您可以使用两种方式:

你可以在fragment内部创建一个方法,但首先你必须创建一个View属性并将inflater结果放入其中,然后在onCreateView中返回:

1° 打开您的 Fragment 类。创建属性

private View view;

2° 将 'view' 属性分配给 onCreateView 中的充气器

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                view = inflater.inflate(R.layout.your_activity_main, container, false);
                return view;
}

3° 创建方法 'hideKeyboard'

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

5° 现在只需调用方法

    hideKeyboard(getActivity());

如果这不能解决您的问题,您可以尝试将 MainActivity 类作为对象传递以关闭 Frament 类中的键盘

1° 在您实例化 Fragment 的 YourClassActivity 中,创建方法 'hideKeyboard'

public class YourClassActivity extends AppCompatActivity {
    public static void hideKeyboard(Activity activity) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            //Find the currently focused view, so we can grab the correct window token from it.
            View view = activity.getCurrentFocus();
            //If no view currently has focus, create a new one, just so we can grab a window token from it
            if (view == null) {
                view = new View(activity);
            }
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
}

2° 在实例化 Fragment 的 Activity 中实现 'Serializable' 接口

public class YourClassActivity extends AppCompatActivity implements Serializable {
...
}

3°在Activity中实例化Frament时,必须将参数传递给那个Fragment,即Activity类本身

Bundle bundle = new Bundle();
bundle.putSerializable("activity", this);
YourClassFragment fragment = new YourClassFragment();
fragment.setArguments(bundle);

4° 现在让我们进入您的 Fragment 类。创建属性视图和活动。

private View view;  
private Activity activity;

5° 在 onCreateView 中将 'view' 属性分配给充气机。在这里,您将检索作为此 Fragment 的参数传递的 Activity 对象

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.your_activity_main, container, false);
            activity = (Activity) getArguments().getSerializable("obj");
    
            return view;
    }

6° 现在只需调用方法

hideKeyboard(activity);

答案 13 :(得分:0)

开始

在片段中,下面的代码(在 onActivityCreated 中使用)强制在开头隐藏键盘:

<mat-form-field appearance="legacy" [style.width.%]="45">
  <mat-label>Phasenende</mat-label>
  <input
    *ngIf="this.projectPhases <= 1"
    matInput
    [min]="this.projectForm.controls['phases'].value[i].pStart"
    placeholder="Ende"
    [matDatepicker]="picker2"
    formControlName="pEnd"
  />
  <input
    *ngIf="this.projectPhases > 1"
    matInput
    [min]="this.projectForm.controls['phases'].value[i-1].pEnd"
    placeholder="Ende"
    [matDatepicker]="picker2"
    formControlName="pEnd"
  />
  <mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
  <mat-datepicker #picker2></mat-datepicker>
</mat-form-field>

在碎片期间(如果需要)

而且如果你有 edittext 或 sth 不同的需要键盘,并且想在按下键盘外时隐藏键盘(在我的例子中我在 xml 中有 LinearLayout 类),首先初始化布局:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Objects.requireNonNull(getActivity()).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}

然后,您需要以下代码(在 onViewCreated 中使用):

LinearLayout linearLayout;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
    View view = inflater.inflate(R.layout.<your fragment xml>, container, false);

    linearLayout= view.findViewById(R.id.linearLayout);
    ...
    return view;
}

答案 14 :(得分: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);
   }
});

答案 15 :(得分:0)

在科特林:

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

答案 16 :(得分:0)

只需在您的代码中添加以下行:

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

答案 17 :(得分:0)

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