본문 바로가기
Android/Dev

Fragment 를 사용할 때 EditText의 Focus를 없애기

by featherwing 2018. 2. 23.
반응형

EditText의 외부를 클릭해서 EditText의 Focus를 없애고 키보드를 내리기 위한 방법을 찾다보니, 많은 예제에서 다음의 방법을 제시하고 있습니다.

 

1. editText의 상위 레이아웃 XML에 다음의 속성 부여.   

    android:clickable="true" 
    android:focusableInTouchMode="true" 

 

2.1 editText에 onFocusChangeListener 적용.

 edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                 InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
                 inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);            }
        }
    });

2.2 상위레이아웃에 onTouchListener 적용.

 

FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor);
touchInterceptor.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (mEditText.isFocused()) {
                Rect outRect = new Rect();
                mEditText.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                    mEditText.clearFocus();
                    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        }
        return false;
    }
});

2.3 XML 상에 더미 레이아웃을 따로 만들어서 더미 레이아웃에 상기와 유사한onTouchListener를 적용 

 

하는 등의 방법이 있었습니다.

 

적용하기 위해 onFocusChangeListener나 onTouchListener 등의 내부에 로그를 달아봐도 로그가 찍히지 않아 사용할 수 없다고 판단하였습니다.

 

stackOverflow에서 많은수의 useful을 받은 방법들이었는데

Activity에서 그대로 사용할 때는 작동될것으로 보이나 Fragment에서는

상위 activity가 터치나 클릭을 intercept하기 때문에 작동하지 않는것으로 생각합니다.

 

 

Fragment에서 발생하는 문제의 해결방법은 언제나 Activity를 조작해 주는것으로 해결되었기 때문에 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 );

}

 

 

메인액티비티에 상기의 코드를 추가해 주는것만으로 EditText의 clearFocus를 실행하고, 키보드를 숨기는것이 문제없이 작동하는것을 확인하였습니다.

 

 

Fragment를 사용할 때마다 느끼지만, 유용하면서도 복잡해서 언제나 오묘합니다.

 

 

반응형

댓글