点击Fragment外部时如何隐藏Android软键盘

7
我有一个包含EditText的片段用于输入,但现在我想在用户点击EditText之外的屏幕时关闭键盘。
我知道如何在Activity中实现这一点,但是在片段中似乎不同。
我正在调用该方法view.onTouchListener。
public static void hideSoftKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);

inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}

有没有解决方案,谢谢

7个回答

25
在片段的父Activity中,重写以下方法:
 @Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View v = getCurrentFocus();
        if ( v instanceof EditText) {
            Rect outRect = new Rect();
            v.getGlobalVisibleRect(outRect);
            if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                v.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

在片段的布局中使用此属性:

android:focusableInTouchMode="true"

希望这能对您有所帮助。


这个答案有帮助解决你的问题吗? - Kanchan Chowdhury
1
它将适用于活动和活动的所有片段。您应该在所有想要该行为的布局中使用属性android:focusableInTouchMode="true"。 - Kanchan Chowdhury
即使没有使用 android:focusableInTouchMode="true",也能正常工作。谢谢。 - Mustafa Demir
当使用片段时,函数dispatchTouchEvent不会被调用。我在父活动中进行了重写,并在片段布局上使用了android:focusableInTouchMode,但没有成功。 - R. A.

1
使用这个方法,它可以正常工作。
public static void hideKeyBoardMethod(final Context con, final View view) {
        try {
            view.post(new Runnable() {
                @Override
                public void run() {
                    InputMethodManager imm = (InputMethodManager) con.getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                }
            });

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

我尝试过了,但OnTouchListener和OnClickListener两种方法仍然存在相同的问题。@NIteshPareek - Mehul Gajjar
使用 dispatchTouchEvent() 方法来实现此功能。 - Nitesh Pareek

1
你可以使用这种方法,对我来说运行良好。 只需像这样传递布局根元素的引用即可。
setupUI(rootView.findViewById(R.id.rootParent))

设置UI的代码如下:

public void setupUI(View parentView) {

    //Set up touch listener for non-text box views to hide keyboard.
    if(!(view instanceof EditText)) {

        view.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard();
                handleCallBack();
                return false;
            }
        });
    }

1
我刚刚在该活动的所有片段中重写了dispatchTouchEvent()方法。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // TODO Auto-generated method stub
     if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if ( v instanceof EditText) {
                Rect outRect = new Rect();
                v.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int)ev.getRawX(), (int)ev.getRawY())) {
                    v.clearFocus();
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        } 

在主布局的每个片段的XML中设置属性。
android:focusableInTouchMode="true"

dispatchTouchEvent() 是 Activity 的一个方法,而不是 Fragment。 - CoolMind

0

你也可以这样做

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

希望它有所帮助!


0

如果使用Fragment,请使用以下代码

View view = inflater.inflate(R.layout.fragment_test, container, false);

    view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {

                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    dispatchTouchEvent(event);
                }
                return true;
            }
    });

//here the rest of your code

return view;

应用此代码并调用dispatchTouchEvent()方法


-1
如果您想要在编辑文本框之外触摸,则键盘会自动隐藏,因此请使用以下代码。
public boolean dispatchTouchEvent(MotionEvent event) {

        View view = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(event);

        if (view instanceof EditText) {
            View w = getCurrentFocus();
            int location[] = new int[2];
            w.getLocationOnScreen(location);
            float x = event.getRawX() + w.getLeft() - location[0];
            float y = event.getRawY() + w.getTop() - location[1];
            if (event.getAction() == MotionEvent.ACTION_DOWN
                    && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
            }
        }
        return ret;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接