超简单Fragment使用dispatchTouchEvent(Activity把分发触摸事件给Fragment)+ 超简单Activity点击空白处关闭软键盘除EditText和发送按钮

我是为了实现在Fragment输入框显示的情况下点击空白处隐藏输入框并关闭软键盘(点击EditText和发送按钮不做处理)当然代码是我搬得。

Fragment所依附的Activity

 //1.触摸事件接口
    public interface MyOnTouchListener {
        public boolean onTouch(MotionEvent ev);
    }

    //2. 保存MyOnTouchListener接口的列表
    private ArrayList<MyOnTouchListener> onTouchListeners = new ArrayList<MyOnTouchListener>();

    //3.分发触摸事件给所有注册了MyOnTouchListener的接口
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        for (MyOnTouchListener listener : onTouchListeners) {
            listener.onTouch(ev);
        }
        return super.dispatchTouchEvent(ev);
    }

    //4.提供给Fragment通过getActivity()方法来注册自己的触摸事件的方法
    public void registerMyOnTouchListener(MyOnTouchListener myOnTouchListener) {
        onTouchListeners.add(myOnTouchListener);
    }

    //5.提供给Fragment通过getActivity()方法来注销自己的触摸事件的方法
    public void unregisterMyOnTouchListener(MyOnTouchListener myOnTouchListener) {
        onTouchListeners.remove(myOnTouchListener);
    }

Fragment


private SVCGestureListener mGestureListener = new SVCGestureListener();

private static enum State {
        VISIBLE, ANIMATIONING, INVISIBLE,
    }

    private State state = State.INVISIBLE;

    public class SVCGestureListener implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }

        //点击的时候执行
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            //          toolbar.changeVisibility();
            if (state == State.VISIBLE) {
            } else {
            }
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            return false;
        }
    }
    
((TeacherMainActivity) getActivity()).registerMyOnTouchListener(new TeacherMainActivity.MyOnTouchListener() {
            @Override
            public boolean onTouch(MotionEvent event) {

                // TextView tvSend = chatKeyboard.getTvSend();sendCommentTv为发送按钮
                int[] leftTop = {0, 0};
                //获取输入框当前的location位置
                sendCommentTv.getLocationInWindow(leftTop);
                int left = leftTop[0];
                int top = leftTop[1];
                int bottom = top + sendCommentTv.getHeight();
                int right = left + sendCommentTv.getWidth();
                int x = (int) event.getX();
                int y = (int) event.getY();
                if (x > left && x < right && y > top && y < bottom) {
                    // 点击的是发送按钮,保留点击EditText的事件
                    // 必不可少,否则所有的组件都不会有TouchEvent了
                    if (getActivity().getWindow().superDispatchTouchEvent(event)) {
                        return true;
                    }
                    return mGestureDetector.onTouchEvent(event);
                }
                return handlerOtherTypeDispatchTouchEvent(event);
            }
        });

private boolean handlerOtherTypeDispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            View v = getActivity().getCurrentFocus();
            if (isShouldHideInput(v, event)) {
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                   /* //隐藏输入框
                    commentRela.setVisibility(View.GONE);*/
                    //隐藏软键盘
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
            return mGestureDetector.onTouchEvent(event);
        } else if (action == MotionEvent.ACTION_MOVE) {

        }
        // 必不可少,否则所有的组件都不会有TouchEvent了
        if (getActivity().getWindow().superDispatchTouchEvent(event)) {
            return true;
        }
        return mGestureDetector.onTouchEvent(event);
    }

    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击的是输入框区域,保留点击EditText的事件
                return false;
            } else {
                //使EditText触发一次失去焦点事件
                v.setFocusable(false);
                v.setFocusableInTouchMode(true);
                return true;
            }
        }
        return false;
    }

Activity点击空白处关闭软键盘除EditText和发送按钮

/**
     *
     * View事件传递(解决聊天界面点击除editText区域以外其他位置实现隐藏软键盘----点击发送按钮不隐藏软键盘
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // TextView tvSend = chatKeyboard.getTvSend();tvSend为发送按钮
        int[] leftTop = {0, 0};
        //获取输入框当前的location位置
        sendTv.getLocationInWindow(leftTop);
        int left = leftTop[0];
        int top = leftTop[1];
        int bottom = top + sendTv.getHeight();
        int right = left + sendTv.getWidth();
        int x = (int) event.getX();
        int y = (int) event.getY();
        if (x > left && x < right && y > top && y < bottom) {
            // 点击的是发送按钮,保留点击EditText的事件
            // 必不可少,否则所有的组件都不会有TouchEvent了
            if (getWindow().superDispatchTouchEvent(event)) {
                return true;
            }
            return onTouchEvent(event);
        }
        return handlerOtherTypeDispatchTouchEvent(event);
    }

    private boolean handlerOtherTypeDispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if (isShouldHideInput(v, event)) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
            return super.dispatchTouchEvent(event);
        } else if (action == MotionEvent.ACTION_MOVE) {

        }
        // 必不可少,否则所有的组件都不会有TouchEvent了
        if (getWindow().superDispatchTouchEvent(event)) {
            return true;
        }
        return onTouchEvent(event);
    }

    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击的是输入框区域,保留点击EditText的事件
                return false;
            } else {
                //使EditText触发一次失去焦点事件
                v.setFocusable(false);
                v.setFocusableInTouchMode(true);
                return true;
            }
        }
        return false;
    }
上一篇:九、View事件传递机制


下一篇:在Android中滑动以取消动画