ChatGPT解决这个技术问题 Extra ChatGPT

如何将软键盘隐藏在片段中?

我有一个使用 ViewPager 提供多个片段的 FragmentActivity。每个都是具有以下布局的 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);
}

我保存来自 onCreateView 的传入 ViewGroup container 参数作为访问主要活动的窗口令牌的一种方式。这运行没有错误,但在 onStart 中对 hideSoftInputFromWindow 的调用不会隐藏键盘。

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

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

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

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


I
Ian G. Clifton

只要您的 Fragment 创建一个视图,您就可以在附加视图后使用该视图中的 IBinder(窗口令牌)。例如,您可以在 Fragment 中覆盖 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);
}

我将此添加到我的项目中。但是当我单击另一个选项卡时,它崩溃了。
对于那些这样做并因 NullPointerException 而崩溃的人,只需在片段 onCreateView 方法中使用 InputMethodManager。这样做,您将拥有自己的视图,并且可以使用已膨胀为 imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 的视图更改最后一行
完美的答案,我建议在 Resume 上添加相同的功能来处理它,以防在 viewpager 中创建了许多片段并且其中一个片段需要在创建后隐藏键盘
S
Shajeel Afzal

除了以下代码行对我有用:

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

SOFT_INPUT_STATE_HIDDEN 也对我有用,但我不知道它与 `SOFT_INPUT_STATE_ALWAYS_HIDDEN' 之间的区别是什么。
第一个答案没有用,这个成功了。谢谢
谢谢你节省了我的时间,伙计。
我的情况是我正在使用片段/TabView。第一个选项卡在 TextView 中有“提示”。第二个选项卡有一个活动,其中我有 EditText(s) 和“editText1.setShowSoftInputOnFocus(false);”命令集和我自己的自定义键盘。当我将应用程序置于后台,然后将应用程序带回视图时,会弹出不需要的软键盘。在 onStart Life Cycle Override 方法中设置上述命令会停止此操作。谢谢@Shajeel Afzal
E
Eric Schlenz

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

(添加到您的 Activity 的清单定义中):

android:windowSoftInputMode="stateHidden"

谢谢,这就是我最终做的。但是,我仍然想知道如何使用输入法管理器来显示/隐藏键盘,因为我可能需要在活动开始后的某个时间使用它。
M
MrEngineer13
    @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() 而不是保留我的视图实例。
onCreate 是 Fragment 之外的一个类,因此我将它传递给 rootView 以便能够使用它来删除该类中的 phoneKeyPad。我想他们想要从 Fragment 内部而不是 Fragment 中的一个类。
m
macio.Jun

DialogFragment 的例外情况是,必须隐藏嵌入式 Dialog 的焦点,而只能隐藏嵌入式 Dialog 中的第一个 EditText

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

如果您有 DialogFragment,这是隐藏键盘的唯一方法。
在哪里写这个?
@Mstack,适用于 onActivityCreated() 方法。override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
A
André Ramon

此代码适用于片段:

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

N
Nazmus Saadat

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

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


M
Meerz

当我在标签中从一个片段切换到另一个片段时,这将适用于我的情况

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

如果您有标签片段并且只想为几个标签隐藏键盘,请使用它。
A
Ali Nawaz

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

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

h
hiddeneyes02

这对 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(true); getView().setFocusableInTouchMode(true); getView().requestFocus(); }
Q
Quick learner

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

}

兄弟,你刚刚为我节省了超过 48 小时的工作时间!
S
Stan Peng

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

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

有效,但您必须检查 getActivity().getCurrentFocus().getWindowToken() 是否不为空,否则如果没有焦点编辑文本,则会导致错误。请看下面我的回答
R
RonaldPaguay

科特林代码

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

M
Mike

只需在您的代码中添加这一行:

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

t
timeSmith

在科特林:

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

D
Duc Trung Mai

用这个:

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

n
n-y

开始

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

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

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

在片段期间(如果需要)

并且如果您有edittext或其他不同需求的键盘,并且想要在键盘外按下时隐藏键盘(在我的情况下,我在xml中有LinearLayout类),首先初始化布局:

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

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

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

    linearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view12) {
            try {
                InputMethodManager inputMethodManager = (InputMethodManager) Objects.requireNonNull(VideoFragment.this.getActivity()).getSystemService(INPUT_METHOD_SERVICE);
                assert inputMethodManager != null;
                inputMethodManager.hideSoftInputFromWindow(VideoFragment.this.getActivity().getCurrentFocus().getWindowToken(), 0);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}

M
Moises

您可以使用两种方式:

您可以在片段内创建一个方法,但首先您必须创建一个 View 属性并将充气结果放入其中,然后再返回 onCreateView:

1° 打开你的 Fragment 课程。创建属性

private View view;

2° 在 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°在你的Activity中实现'Serializable'接口来实例化Fragment

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

3° 当你在Activity中实例化Fragment时,你必须将参数传递给那个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 中为充气机分配“视图”属性。在这里,您将检索作为此 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);

M
Mohamed Mohamed Taha

我做了所有步骤,但是缺少一些东西我用这种方法将键盘隐藏在片段中

fun hideKeyBoard(view: View) {
        val inputManager =
            requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputManager.hideSoftInputFromWindow(
            view.windowToken,
            SOFT_INPUT_STATE_ALWAYS_HIDDEN
        )
    }

但是当我打开片段时,经过大量搜索后键盘也打开了我发现问题我必须将这些代码放在我的 xml 布局根目录中

android:focusable="true"
android:focusableInTouchMode="true" 

注意:如果您删除上述方法并将属性放在根布局中,它将正常工作。