EditText 외부를 클릭 한 후 안드로이드에서 소프트 키보드를 숨기는 방법은 무엇입니까?


354

누구나 키보드를 숨기려면 구현해야한다는 것을 모두 알고 있습니다.

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

그러나 여기서 가장 중요한 것은 사용자가 소프트 키보드가 아닌 다른 장소를 만지거나 선택할 때 키보드를 숨기는 방법입니다 EditText.

onTouchEvent()부모님 을 사용하려고했지만 Activity사용자가 다른보기 외부를 만지고 스크롤보기가없는 경우에만 작동합니다.

나는 터치, 클릭, 포커스 리스너를 성공없이 구현하려고했습니다.

터치 이벤트를 가로 채기 위해 자체 스크롤보기를 구현하려고했지만보기를 클릭하지 않고 이벤트의 좌표 만 가져올 수 있습니다.

이것을 수행하는 표준 방법이 있습니까 ?? iPhone에서는 정말 쉬웠습니다.


스크롤보기가 실제로 문제가 아니라 레이블이라는 것을 깨달았습니다. 뷰는 뭔가 수직 레이아웃입니다 : 등 텍스트 뷰, 글고, 텍스트 뷰, 글고 .. 그리고 textViews 키보드 느슨한 초점에 글고 치기를하자 숨길 것
htafoya

해결 방법은 getFields()여기 를 참조하십시오 : stackoverflow.com/questions/7790487/…
Reto

키보드는 나는이 노력이 가치가 있는지가 의문이다라고 말하고 싶지만 그래서, Enter 키를 눌러서 버튼에 의해 폐쇄 될 수있다
gerrytan

4
이 답변을 찾았습니다 : stackoverflow.com/a/28939113/2610855 가장 좋은 방법.
Loenix

답변:


575

다음 스 니펫은 단순히 키보드를 숨 깁니다.

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = 
        (InputMethodManager) activity.getSystemService(
            Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
        activity.getCurrentFocus().getWindowToken(), 0);
}

이것을 유틸리티 클래스에 넣거나 활동 내에서 정의하는 경우 활동 매개 변수를 피하거나을 호출하십시오 hideSoftKeyboard(this).

가장 까다로운 부분은 언제 전화해야하는지입니다. View활동의 모든 과정을 반복하는 메소드를 작성하고 해당 컴포넌트에 instanceof EditText등록되어 있지 않은지 확인 setOnTouchListener하고 모든 것이 제자리에 있는지 확인하십시오 . 그렇게하는 방법이 궁금하다면 실제로 매우 간단합니다. 여기에 당신이하는 일이 있습니다. 다음과 같은 재귀 적 방법을 작성하십시오. 실제로이를 사용하여 사용자 정의 서체 설정과 같은 것을 할 수 있습니다 ... 여기에 방법이 있습니다

public void setupUI(View view) {

    // Set up touch listener for non-text box views to hide keyboard.
    if (!(view instanceof EditText)) {
        view.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(MyActivity.this);
                return false;
            }
        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupUI(innerView);
        }
    }
}

그게 전부 setContentView입니다. 활동을 마친 후에이 메소드를 호출 하십시오. 전달할 매개 변수가 궁금한 경우 id상위 컨테이너의 매개 변수 입니다. 다음 id과 같이 부모 컨테이너에

<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>

전화 setupUI(findViewById(R.id.parent)), 그게 다야.

이를 효과적으로 사용하려면 확장을 작성 Activity하고이 메소드를 삽입하고 애플리케이션의 다른 모든 활동이이 활동을 확장 setupUI()하고 onCreate()메소드 에서 호출하도록 할 수 있습니다.

도움이 되길 바랍니다.

둘 이상의 활동을 사용하는 경우 공통 ID를 상위 레이아웃에 정의하십시오. <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

그런 다음 클래스를 확장하고 클래스 내 에서 Activity정의 하고``활동 대신이 클래스를 확장하십시오.setupUI(findViewById(R.id.main_parent))OnResume()in your program


위 함수의 Kotlin 버전은 다음과 같습니다.

@file:JvmName("KeyboardUtils")

fun Activity.hideSoftKeyboard() {
    currentFocus?.let {
        val inputMethodManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)!!
        inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0)
    }
}

나는 나 자신을 테스트하지는 않았지만 효과가있는 것처럼 보이며 높은 리뷰가 있으므로 허용 된 답변을 이것으로 바꿀 것입니다.
htafoya

4
그렇게 힘들지 않아야합니까? 지금 안드로이드 프로그래밍을 사용하지 않아서 틀렸다면 수정 해주세요. 언제든 포커스가있는 EditText를 추적하고 OnTouchEvent 중에 포커스가 없어 지도록 요청할 수 있습니까?
Navneeth G

25
다른 사람 이이 문제를 겪었는지 확실하지 않지만 포커스가 없으면 hideSoftKeyboard를 호출하면 앱이 중단됩니다. 이 방법의 두 번째 줄을 둘러싸면이를 해결할 수 있습니다.if(activity.getCurrentFocus() != null) {...}
Frank Cangialosi

14
이 접근법의 문제점은 다른 모든 뷰가 뷰를 설정할 필요가 없다고 가정한다는 OnTouchListener것입니다. 그 논리를 ViewGroup.onInterceptTouchEvent(MotionEvent)루트보기로 설정할 수 있습니다.
Alex.F

2
키보드를 열어 둔 상태에서 다른 컨트롤을 클릭해도 작동하지 않음
mohitum

285

다음 단계를 수행하여이를 달성 할 수 있습니다.

  1. 다음 속성을 추가하여 상위보기 (활동의 컨텐츠보기)를 클릭 가능하고 집중 가능하게하십시오.

        android:clickable="true" 
        android:focusableInTouchMode="true" 
  2. hideKeyboard () 메소드 구현

        public void hideKeyboard(View view) {
            InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
  3. 마지막으로 편집 텍스트의 onFocusChangeListener를 설정하십시오.

        edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideKeyboard(v);
                }
            }
        });

아래 주석 중 하나에서 지적했듯이 부모보기가 ScrollView 인 경우 작동하지 않을 수 있습니다. 이러한 경우 클릭 가능 및 포커스 가능 InTouchMode가 ScrollView 바로 아래의보기에 추가 될 수 있습니다.


67
제 생각에는 이것이 정답입니다. 코드가 적고 불필요한 반복이 없습니다.
gattshjoty

14
나는이 대답을 많이 좋아합니다. 주의 할 점은이 추가 할 때 나를 위해 작동하지 않은 것입니다 clickablefocusableInTouchMode내 루트에 ScrollView요소입니다. 나는 내 직접 부모에게 추가해야 EditText했습니다 LinearLayout.
Adam Johns

10
나를 위해 완벽하게 일했습니다. 그러나 두 개의 편집 텍스트 위젯이있는 경우 두 위젯 모두에서 초점을 올바르게 처리해야합니다. 그렇지 않으면 키보드 숨기기가 불필요하게 토글됩니다.
Marka A

1
@MarkaA 나는 이것에 문제가 없었습니다. 다른 EditText를 클릭하면 키보드가 그대로 유지됩니다. 배경을 클릭하면 키보드가 숨겨져 있습니다. onFocusChange에서 다른 처리를 했으므로 포커스가있을 때 EditText의 배경을 변경하면 열이 없습니다.
CularBytes

3
@Shrikant-여러 편집 텍스트로 깜박임이 발생했습니다. 방금 각 편집 텍스트 대신 부모에서 onFocusChangeListener를 설정하고 조건을 다음과 같이 변경했습니다. (hasFocus) {hideKeyboard (v); } btwn 편집 텍스트 전환이 더 이상 깜박 거리지 않습니다.
manisha

69

활동에서 아래 코드를 재정의하십시오.

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

4
간단한 해결책, 활동에 추가하면 조각도 처리됩니다.
Rohit Maurya

1
또 다른 해결책은 BaseActivity를 작성하고 모든 활동을 확장하는 것이다
SUMIT을 sonawane

1
훌륭한 솔루션
Ahmed Adel Ismail 1

1
키보드를 닫을 때 화면이 깜빡 거리지 않도록 저장했습니다. 엄지 손가락!
Dimas Mendes

1
좋았지 만 사실이 되기에는 너무 좋았습니다. 간단하고 매우 짧았으며 작동했습니다 ... 아아, 문제가 있습니다 : 키보드가 표시되면 키보드를 요청한 EditText를 터치 할 때마다 키보드가 내려갑니다. 자동으로.
Chrysotribax

60

수락 된 답변이 약간 복잡하다는 것을 알았습니다.

여기 내 해결책이 있습니다. OnTouchListener기본 레이아웃에을 추가하십시오 .

findViewById(R.id.mainLayout).setOnTouchListener(this)

다음 코드를 onTouch 메소드에 넣습니다.

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

이렇게하면 모든 뷰를 반복 할 필요가 없습니다.


@roepit-레이아웃을 뷰로 캐스트하려고하는 classCastexception을 가져옵니다. 내가 뭔가를 놓치고 있습니까?
katzenhut

어딘가에서 코드를 참조 할 수 있습니까? 레이아웃과 활동 / 조각 및 기타 코드를 볼 수 없을 때 무엇이 ​​잘못되었는지 말할 수 없습니다.
roepit

가장 좋은 대답은 여전히 ​​어떻게 작동하는지 내 머리를 감싸려고합니다.
user40797

앱의 제목 표시 줄을 클릭하면 작동합니까?
user1506104

1
키보드를 숨기는 데 완벽하게 작동합니다! 이것은 실제로 EditText의 초점을 해제하지 않고 키보드를 숨 깁니다. EditText의 초점을 해제하려면 예 android:onClick="stealFocusFromEditTexts"를 들어 부모보기의 xml에 추가 한 다음 public void stealFocusFromEditTexts(View view) {}활동에 추가하십시오. on-click 방법은 아무것도 할 필요가 없으며, 부모 뷰가 초점을 맞추거나 선택 가능하도록해야하기 때문에 자식에서 포커스를 훔치기 위해 필요합니다. EditText
Jacob R

40

키보드를 숨기는 솔루션이 하나 더 있습니다.

InputMethodManager imm = (InputMethodManager) getSystemService(
    Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

여기서 전달 HIDE_IMPLICIT_ONLY의 위치 showFlag0의 위치 hiddenFlag. 소프트 키보드가 강제로 닫힙니다.


3
고마워요 ..... 무엇보다도 시도했지만 대화 상자 editext 텍스트 nd closoing 대화 상자에서 가치를 얻는 동안 작동하지 않습니다 ...
PankajAndroid

고마워, 이것은 작동하고 있으며 위의 다른 것보다 훨씬 깨끗합니다! +1
Edmond Tamas

예상대로 작동합니다. 솔루션에 감사드립니다 +1
tryp

나를 위해 매력처럼 작동합니다. 우아한 솔루션 +1
saintjab

2
죄송하지만이 방법은 전환되어 있으므로 키보드 상태가 이미 닫혀 있으면 키보드가 표시됩니다
HendraWD

16

글쎄, 나는 다소 문제를 해결하고, 활동에 dispatchTouchEvent를 무시하고, 키보드를 숨기기 위해 다음을 사용하고 있습니다.

 /**
 * Called to process touch screen events. 
 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    switch (ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchDownTime = SystemClock.elapsedRealtime();
            break;

        case MotionEvent.ACTION_UP:
            //to avoid drag events
            if (SystemClock.elapsedRealtime() - touchDownTime <= 150){  

                EditText[] textFields = this.getFields();
                if(textFields != null && textFields.length > 0){

                    boolean clickIsOutsideEditTexts = true;

                    for(EditText field : textFields){
                        if(isPointInsideView(ev.getRawX(), ev.getRawY(), field)){
                            clickIsOutsideEditTexts = false;
                            break;
                        }
                    }

                    if(clickIsOutsideEditTexts){
                        this.hideSoftKeyboard();
                    }               
                } else {
                    this.hideSoftKeyboard();
                }
            }
            break;
    }

    return super.dispatchTouchEvent(ev);
}

편집 : getFields () 메서드는보기에서 텍스트 필드가있는 배열을 반환하는 메서드 일뿐입니다. 터치 할 때마다이 배열을 만들지 않기 위해 getFields () 메서드에서 반환되는 sFields라는 정적 배열을 만들었습니다. 이 배열은 다음과 같은 onStart () 메소드에서 초기화됩니다.

sFields = new EditText[] {mUserField, mPasswordField};


완벽하지는 않습니다. 드래그 이벤트 시간은 휴리스틱에만 기반하기 때문에 긴 성직자를 수행 할 때 숨기지 않는 경우가 많으며 뷰당 모든 editText를 가져 오는 방법도 작성했습니다. 그렇지 않으면 다른 EditText를 클릭 할 때 키보드가 숨겨져 표시됩니다.

더 깨끗하고 짧은 솔루션은 환영합니다


8
나중에 다른 사람들을 돕기 위해, getFields()방법 을 포함하도록 답변에서 코드를 편집하는 것을 고려 하시겠습니까? 정확할 필요는 없으며 EditText객체 배열을 반환한다는 것을 나타내는 주석 만있는 예제 일뿐 입니다.
Squonk

14

OnFocusChangeListener를 사용하십시오 .

예를 들면 다음과 같습니다.

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            hideKeyboard();
        }
    }
});

업데이트 : onTouchEvent()활동을 재정의 하고 터치 좌표를 확인할 수도 있습니다 . 좌표가 EditText 외부에 있으면 키보드를 숨 깁니다.


9
문제는 레이블이나 초점을 맞출 수없는 다른보기를 클릭 할 때 편집 텍스트의 초점이 느슨해지지 않는다는 것입니다.
htafoya

이 경우 솔루션이 하나 더 있습니다. 답변을 업데이트했습니다.
Sergey Glotov

2
onTouchEvent가 여러 번 호출되었으므로 이는 좋은 습관이 아닙니다.
Jesus Dimrix

13

이를 위해 Activity에서 dispatchTouchEvent를 구현했습니다.

private EditText mEditText;
private Rect mRect = new Rect();
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    int[] location = new int[2];
    mEditText.getLocationOnScreen(location);
    mRect.left = location[0];
    mRect.top = location[1];
    mRect.right = location[0] + mEditText.getWidth();
    mRect.bottom = location[1] + mEditText.getHeight();

    int x = (int) ev.getX();
    int y = (int) ev.getY();

    if (action == MotionEvent.ACTION_DOWN && !mRect.contains(x, y)) {
        InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        input.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

나는 그것을 테스트하고 완벽하게 작동합니다!


작동하지만 이것의 문제는 우리가 하나 이상의 EditText를 가지고 있다면 우리도 그것을 고려해야한다는 것입니다. 그러나 나는 당신의 대답을 좋아했습니다 :-)
Lalit Poptani

getActionMasked (ev)는 더 이상 사용되지 않으므로 이제 다음을 사용하십시오. final int action = ev.getActionMasked (); 첫 번째 줄.
Andrew

12

코 틀린재질 디자인 사용 방법 TextInputEditText (이 방법은과도 호환 EditTextView ) ...

1. 다음 속성을 추가하여 상위 뷰 (활동 / 조각의 컨텐츠 뷰)를 클릭하고 초점을 맞 춥니 다.

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

2. 모든 View의 확장명을 만듭니다 (예 : ViewExtension.kt 파일 내부).

fun View.hideKeyboard(){
    val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.hideSoftInputFromWindow(this.windowToken, 0)
}

3. TextInputEditText를 상속하는 BaseTextInputEditText를 작성하십시오. 보기에 초점이 맞지 않을 때 키보드를 숨기려면 onFocusChanged 메소드를 구현하십시오.

class BaseTextInputEditText(context: Context?, attrs: AttributeSet?) : TextInputEditText(context, attrs){
    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        if (!focused) this.hideKeyboard()
    }
}

4. XML에서 새로운 사용자 정의보기를 호출하십시오.

<android.support.design.widget.TextInputLayout
        android:id="@+id/textInputLayout"
        ...>

        <com.your_package.BaseTextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            ... />

    </android.support.design.widget.TextInputLayout> 

그게 다야. 이 반복적 인 사례를 처리하기 위해 컨트롤러 (조각 또는 활동) 를 수정할 필요가 없습니다 .


그래, 좋은 방법이지만 더 간단한 방법이 있었으면 좋겠다!
devDeejay

11

모든 활동에서 공개 부울 dispatchTouchEvent (MotionEvent 이벤트)를 대체하거나 활동 클래스를 확장하십시오.

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    View view = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

    if (view instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];

        if (event.getAction() == MotionEvent.ACTION_UP 
 && (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;
}

그리고 그게 당신이해야 할 전부입니다


이것이 내가 작동하게하는 가장 쉬운 방법이었습니다. 여러 EditText 및 ScrollView와 함께 작동
RJH

여러 개의 EditText로 테스트했습니다. 효과가있다! 유일한 단점은 드래그 이동을 할 때도 숨겨진다는 것입니다.
RominaV

9

Andre Luis IM의 솔루션을 수정했습니다.

Andre Luiz IM과 같은 방식으로 소프트 키보드를 숨기는 유틸리티 방법을 만들었습니다.

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

그러나 성능이 떨어지는 모든보기에 OnTouchListener를 등록하는 대신 루트보기 만 OnTouchListener를 등록했습니다. 이벤트가 소비 될 때까지 버블 링되므로 (EditText는 기본적으로 소비하는 뷰 중 하나입니다) 루트보기에 도달하면 소비되지 않았기 때문에 소프트 키보드를 닫습니다.

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

1
이것은 나에게 더 안전한 것 같습니다.
superarts.org

9

나는이 스레드가 상당히 오래되었다는 것을 알고 있으며 정답은 유효하고 많은 해결책이 있지만, 아래의 접근 방식은 효율성과 우아함에 대한 추가 이점을 가질 수 있다고 생각합니다.

모든 활동에 대해이 동작이 필요하므로 Activity 클래스에서 상속되는 CustomActivity 클래스를 작성 하고 dispatchTouchEvent 함수를 "후크"했습니다 . 주의해야 할 두 가지 조건이 있습니다.

  1. 포커스가 변경되지 않고 누군가 현재 입력 필드 외부를 두드리면 IME를 해제하십시오.
  2. 포커스가 변경되고 다음 포커스 요소가 입력 필드의 인스턴스가 아닌 경우 IME를 해제하십시오.

이것은 내 결과입니다.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if(ev.getAction() == MotionEvent.ACTION_UP) {
        final View view = getCurrentFocus();

        if(view != null) {
            final boolean consumed = super.dispatchTouchEvent(ev);

            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view)) {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y)) {
                    return consumed;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText) {
                return consumed;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return consumed;
        }
    }       

    return super.dispatchTouchEvent(ev);
}

참고 : 또한이 속성을 루트보기에 할당하여 모든 입력 필드에 대한 초점을 지우고 입력 필드가 활동 시작에 초점을 맞추지 못하게합니다 (콘텐츠보기를 "포커스 캐처"로 만듭니다).

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final View view = findViewById(R.id.content);

    view.setFocusable(true);
    view.setFocusableInTouchMode(true);
}

훌륭한 감사합니다! 나는 당신의 대답에 대해 하나의 공감대를 넣었습니다.
vijay

2
복잡한 레이아웃에 가장 적합한 솔루션이라고 생각합니다. 그러나 지금까지 2 가지 단점이 있습니다. 1. EditText 컨텍스트 메뉴를 클릭 할 수 없습니다-클릭하면 EditText에서 포커스를 잃을 수 있습니다. 2. EditText 가보기의 맨 아래에 있고 길게 클릭하면 (단어를 선택하기 위해), 그 후에 키보드 우리의 "클릭 포인트"가 EditText가 아니라 키보드에 있다는 것을 보여주었습니다. 그래서 우리는 다시 초점을 잃습니다 : /
sosite

@sosite, 나는 내 대답에서 이러한 한계를 해결했다고 생각합니다. 구경하다.
Andy Dennie

6

나는 dispatchTouchEventhtafoya 의 전화 방식이 마음에 들었습니다 .

  • 타이머 부분을 이해하지 못했습니다 (정지 시간을 측정 해야하는 이유를 모르십니까?)
  • 모든보기 변경마다 모든 EditText를 등록 / 등록 취소하고 싶지 않습니다 (복잡한 계층 구조에서 상당히 많은 viewchanges 및 edittext 일 수 있음)

따라서이 다소 쉬운 솔루션을 만들었습니다.

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    // all touch events close the keyboard before they are processed except EditText instances.
    // if focus is an EditText we need to check, if the touchevent was inside the focus editTexts
    final View currentFocus = getCurrentFocus();
    if (!(currentFocus instanceof EditText) || !isTouchInsideView(ev, currentFocus)) {
        ((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE))
            .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
    return super.dispatchTouchEvent(ev);
}

/**
 * determine if the given motionevent is inside the given view.
 * 
 * @param ev
 *            the given view
 * @param currentFocus
 *            the motion event.
 * @return if the given motionevent is inside the given view
 */
private boolean isTouchInsideView(final MotionEvent ev, final View currentFocus) {
    final int[] loc = new int[2];
    currentFocus.getLocationOnScreen(loc);
    return ev.getRawX() > loc[0] && ev.getRawY() > loc[1] && ev.getRawX() < (loc[0] + currentFocus.getWidth())
        && ev.getRawY() < (loc[1] + currentFocus.getHeight());
}

한 가지 단점이 있습니다.

하나 EditText에서 다른 것으로 전환 EditText하면 키보드가 숨겨지고 다시 표시됩니다. 필자의 경우 두 입력 구성 요소 사이에서 전환되었음을 보여주기 때문에 그런 식으로 원합니다.


이 방법은 내 FragmentActivity로 플러그 앤 플레이 할 수 있다는 점에서 가장 효과적이었습니다.
BillyRayCyrus

고마워, 가장 좋은 방법이야! 방금 이벤트 동작 확인을 추가했습니다. int action = ev.getActionMasked (); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {...}
sergey.n

감사 ! 당신은 내 시간을 절약했습니다. .Best answer.
I.d007

6

탄원 : 나는 영향력이 없다는 것을 알고 있지만, 대답을 진지하게 받아들이십시오.

문제 : 키보드에서 멀리 클릭하거나 최소한의 코드로 텍스트를 편집 할 때 소프트 키보드를 닫습니다.

솔루션 : Butterknife로 알려진 외부 라이브러리 .

한 줄 솔루션 :

@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }

더 읽기 쉬운 솔루션 :

@OnClick(R.id.activity_signup_layout) 
public void closeKeyboard() {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

설명 : OnClick 리스너를 활동의 XML 레이아웃 상위 ID에 바인드하여 레이아웃 (편집 텍스트 또는 키보드가 아님)을 클릭하면 키보드를 숨길 코드 스 니펫을 실행합니다.

예 : 레이아웃 파일이 R.layout.my_layout이고 레이아웃 ID가 R.id.my_layout_id 인 경우 버터 나이프 바인드 호출은 다음과 같아야합니다.

(@OnClick(R.id.my_layout_id) 
public void yourMethod {
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

버터 나이프 문서 링크 : http://jakewharton.github.io/butterknife/

플러그 : 버터 나이프는 안드로이드 개발에 혁명을 일으킬 것입니다. 생각 해보세요.

참고 : 외부 라이브러리 Butterknife를 사용하지 않고도 동일한 결과를 얻을 수 있습니다. 위에서 설명한대로 OnClickListener를 상위 레이아웃으로 설정하십시오.


훌륭하고 완벽한 솔루션! 감사합니다.
nullforlife

6

kotlin에서는 다음을 수행 할 수 있습니다. 모든 뷰를 반복 할 필요가 없습니다. 조각에도 적용됩니다.

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    currentFocus?.let {
        val imm: InputMethodManager = getSystemService(
            Context.INPUT_METHOD_SERVICE
        ) as (InputMethodManager)
        imm.hideSoftInputFromWindow(it.windowToken, 0)
    }
    return super.dispatchTouchEvent(ev)
}

조각에서 작동하지 않습니다
Nurseyit Tursunkulov

이것은 작동하지만 버그가 있습니다. 예를 들어 텍스트보기에 텍스트를 붙여 넣으려면 키보드가 숨겨져 나타납니다. 조금 성가신입니다.
조지 Shalvashvili

그래서 나에게 최고의 솔루션을 말해 ..
사이

4

다음은 사이트에서 제기 된 문제를 해결하는 fje의 답변에 대한 또 다른 변형입니다.

여기서 아이디어는 활동 dispatchTouchEvent방법 에서 아래로 및 위로 작업을 모두 처리 하는 것입니다. 다운 액션에서는 현재 초점이 맞춰진 뷰 (있는 경우)와 터치가 내부에 있는지 여부를 기록하여 나중에 정보 비트를 모두 저장합니다.

우리는 먼저 다른 조치에 초점을 맞출 수 있도록 조치를 취합니다. 그 후에 현재 포커스가있는 뷰가 원래 포커스 된 뷰이고 아래쪽 터치가 해당 뷰 안에있는 경우 키보드를 열어 둡니다.

현재 포커스 뷰가 원래 뷰를 초점을 맞추고 다른 경우 그것이이다 EditText, 우리는 열려있는 키보드를 둡니다.

그렇지 않으면 우리는 그것을 닫습니다.

요약하면 다음과 같이 작동합니다.

  • 현재 포커스 EditText가있는 내부를 만질 때 키보드는 열린 상태를 유지합니다
  • 포커스 EditText에서 다른 EditText키보드 로 이동할 때 키보드는 열린 상태를 유지합니다 (닫거나 다시 열지 않음)
  • 현재 초점 EditText이 아닌 다른 곳을 터치 EditText하면 키보드가 닫힙니다.
  • EditText상황에 맞는 작업 표시 줄 (잘라 내기 / 복사 / 붙여 넣기 단추 사용)을 표시하기 위해 길게 누르면 키보드가 열려 있습니다 (UP 작업이 초점을 벗어난 위치 EditText(CAB를위한 공간을 만들기 위해 아래로 이동)). . 그러나 CAB의 버튼을 누르면 키보드가 닫힙니다. 그것은 바람직하거나 바람직하지 않을 수있다. 한 필드에서 잘라 내기 / 복사하고 다른 필드에 붙여 넣으려면 그럴 것입니다. 같은 EditText곳에 다시 붙여 넣으려면 그렇지 않습니다.
  • 포커스 EditText가 화면 하단에 있고 텍스트를 길게 클릭하여 텍스트를 선택하면 EditText포커스 가 유지되므로 원하는대로 키보드가 열립니다. "터치가 뷰 범위 내에 있습니다." 업 액션이 아닙니다.

    private View focusedViewOnActionDown;
    private boolean touchWasInsideFocusedView;
    
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                focusedViewOnActionDown = getCurrentFocus();
                if (focusedViewOnActionDown != null) {
                    final Rect rect = new Rect();
                    final int[] coordinates = new int[2];
    
                    focusedViewOnActionDown.getLocationOnScreen(coordinates);
    
                    rect.set(coordinates[0], coordinates[1],
                            coordinates[0] + focusedViewOnActionDown.getWidth(),
                            coordinates[1] + focusedViewOnActionDown.getHeight());
    
                    final int x = (int) ev.getX();
                    final int y = (int) ev.getY();
    
                    touchWasInsideFocusedView = rect.contains(x, y);
                }
                break;
    
            case MotionEvent.ACTION_UP:
    
                if (focusedViewOnActionDown != null) {
                    // dispatch to allow new view to (potentially) take focus
                    final boolean consumed = super.dispatchTouchEvent(ev);
    
                    final View currentFocus = getCurrentFocus();
    
                    // if the focus is still on the original view and the touch was inside that view,
                    // leave the keyboard open.  Otherwise, if the focus is now on another view and that view
                    // is an EditText, also leave the keyboard open.
                    if (currentFocus.equals(focusedViewOnActionDown)) {
                        if (touchWasInsideFocusedView) {
                            return consumed;
                        }
                    } else if (currentFocus instanceof EditText) {
                        return consumed;
                    }
    
                    // the touch was outside the originally focused view and not inside another EditText,
                    // so close the keyboard
                    InputMethodManager inputMethodManager =
                            (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMethodManager.hideSoftInputFromWindow(
                        focusedViewOnActionDown.getWindowToken(), 0);
                    focusedViewOnActionDown.clearFocus();
    
                    return consumed;
                }
                break;
        }
    
        return super.dispatchTouchEvent(ev);
    }

4

이 코드로 최근 레이아웃을 클릭 가능하게 만들 수 있습니다.

android:id="@+id/loginParentLayout"
android:clickable="true"
android:focusableInTouchMode="true"

그런 다음 해당 레이아웃에 대한 메소드와 OnClickListner를 작성하여 최상위 레이아웃이 터치 될 때 키보드를 닫는 코드를 작성하는 메소드를 호출하는 곳을 터치하십시오. 다음은 두 가지 코드입니다. // OnCreate ()로 작성해야합니다.

 yourLayout.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View view) {
                    hideKeyboard(view);
                }
            });

listner에서 호출 된 메소드 :-

 public void hideKeyboard(View view) {
     InputMethodManager imm =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

4

이 간단한 요구 사항에 대해 허용되는 답변 비트가 복잡하다는 것을 알았습니다. 결함없이 나를 위해 일한 것은 다음과 같습니다.

findViewById(R.id.mainLayout).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            return false;
        }
    });

1
NestedScrollView복잡한 레이아웃 을 사용 하거나 복잡한 경우 허용되는 답변 : stackoverflow.com/a/11656129/2914140을 참조하십시오 . 다른 용기는 접촉 할 수도 있습니다.
CoolMind 2019

3

iPhone과 동일한 문제를 기반으로 한 더 간단한 접근 방식이 있습니다. 편집 텍스트가 포함 된 터치 이벤트에서 배경의 레이아웃을 무시하기 만하면됩니다. 액티비티의 OnCreate에서이 코드를 사용하십시오 (login_fondo는 루트 레이아웃입니다).

    final LinearLayout llLogin = (LinearLayout)findViewById(R.id.login_fondo);
    llLogin.setOnTouchListener(
            new OnTouchListener()
            {
                @Override
                public boolean onTouch(View view, MotionEvent ev) {
                    InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
                            android.content.Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mActivity.getCurrentFocus().getWindowToken(), 0);
                    return false;
                }
            });

1
내가 말했듯이 기억하는 것처럼 폼이 ScrollView 안에없는 경우에만 작동합니다.
htafoya

1
배경 레이아웃에 다른 자식 레이아웃이 포함되어 있으면 잘 작동하지 않습니다.
AxeEffect

onClick이 유일한 옵션은 아니라는 점을 상기시켜 주셔서 감사합니다.
Harpreet

3

소프트 키보드 표시 / 숨기기 방법

InputMethodManager inputMethodManager = (InputMethodManager) currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (isShow) {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        } else {
            inputMethodManager.showSoftInput(currentActivity.getCurrentFocus(), InputMethodManager.SHOW_FORCED);    
        }

    } else {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
        } else {
            inputMethodManager.hideSoftInputFromInputMethod(currentActivity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);    
        }

    }

나는 그들이 유용했으면 좋겠다.


3

이것은 나에게 가장 쉬운 해결책입니다 (나에 의해 해결되었습니다).

키보드를 숨기는 방법입니다.

public void hideKeyboard(View view){
        if(!(view instanceof EditText)){
            InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
        }
    }

이제 hideKeyboardXML 파일의 디자인보기에서 또는 XML 파일의 텍스트보기에서 아래 코드를 작성 하여 활동의 상위 레이아웃의 onclick 속성을 위의 메소드로 설정 하십시오.

android:onClick="hideKeyboard"

2

메소드를 세분화하고 다음 코드를 일부 UI 유틸리티 클래스 (바람직하게는 아니지만)에 넣어서 모든 활동 또는 조각 클래스에서 액세스하여 목적을 달성 할 수 있습니다.

public static void serachAndHideSoftKeybordFromView(View view, final Activity act) {
    if(!(view instanceof EditText)) {
        view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(act);
                return false;
            }
        });
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View nextViewInHierarchy = ((ViewGroup) view).getChildAt(i);
            serachAndHideSoftKeybordFromView(nextViewInHierarchy, act);
        }
    }
}
public static void hideSoftKeyboard (Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

예를 들어 활동에서 호출해야한다고 말하고 다음과 같이 호출하십시오.

UIutils.serachAndHideSoftKeybordFromView(findViewById(android.R.id.content), YourActivityName.this);

주의

findViewById (android.R.id.content)

이것은 현재 그룹의 루트보기를 제공합니다 (루트보기에서 ID를 설정하지 않아야합니다).

건배 :)



2

활동

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
     ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
     return super.dispatchTouchEvent(ev);
 }

ScreenUtils

 public static void hideKeyboard(Context context, IBinder windowToken) {
     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
 }

3
이 코드는 간단하지만 명백한 문제 가 있습니다. 어디에서나 터치 하면 키보드가 닫힙니다 . 즉, EditText의 다른 위치를 눌러 입력 커서를 움직이면 키보드가 숨겨지고 시스템에서 키보드가 다시 나타납니다.
젠장 야채

2

이 코드를 @Overide 클래스에 추가하십시오.

public boolean dispatchTouchEvent(MotionEvent ev) {
    View view = getCurrentFocus();
    if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        view.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + view.getLeft() - scrcoords[0];
        float y = ev.getRawY() + view.getTop() - scrcoords[1];
        if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
            ((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
    }
    return super.dispatchTouchEvent(ev);
}

3
이것이 질문에 대한 답변이 될 수 있지만 답변의 필수 부분과 OP 코드의 문제점을 설명하는 것이 좋습니다.
pirho

네 @ pirho 또한 동의합니다 Haseeb는 적절한 답변을 제공하는 데 집중해야합니다.
Dilip

2
@Dilip 당신은 또한 당신이 동의하는 의견을 찬성 할 수 있다는 것을 알고 있습니까? 이것은 주석 섹션을 깨끗하게 유지하여 실제로 동일한 포인트를 갖는 많은 주석이 없도록하는 것입니다.
pirho

2

모든 뷰를 반복하거나 dispatchTouchEvent를 재정의하는 대신.

왜 Activity의 onUserInteraction ()을 재정의하지 않더라도 사용자가 EditText 외부를 누를 때마다 키보드가 닫히게됩니다.

EditText가 scrollView 안에있는 경우에도 작동합니다.

@Override
public void onUserInteraction() {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
}

이것은 더 나은 답변입니다
ovluca

예! 그것은 매우 깨끗한 답변입니다. 그리고 다른 모든 활동이 확장하는 AbstractActivity를 만들면 앱 전체에서 기본 동작으로 구울 수 있습니다.
wildcat12

1

Fernando Camarago의 솔루션에 약간의 변형이 적용되었습니다. 내 onCreate 메소드에서 단일 onTouchListener를 루트보기에 연결하지만 활동이 아닌보기를 인수로 보냅니다.

        findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {           
        public boolean onTouch(View v, MotionEvent event) {
            Utils.hideSoftKeyboard(v);
            return false;
        }
    });

별도의 Utils 클래스는 ...

    public static void hideSoftKeyboard(View v) {
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

1

이것은 오래되었지만 사용자 정의 클래스를 임박 하여이 작업을 수행했습니다.

public class DismissKeyboardListener implements OnClickListener {

    Activity mAct;

    public DismissKeyboardListener(Activity act) {
        this.mAct = act;
    }

    @Override
    public void onClick(View v) {
        if ( v instanceof ViewGroup ) {
            hideSoftKeyboard( this.mAct );
        }
    }       
}

public void hideSoftKeyboard(Activity activity) {
        InputMethodManager imm = (InputMethodManager)
        getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}

여기서 모범 사례는 Helper 클래스를 만드는 것이며 모든 컨테이너 Relative / Linear Layouts는 이것을 구현해야합니다.

**** 메인 컨테이너 만이 클래스를 구현해야합니다 (최적화) ****

다음과 같이 구현하십시오.

Parent.setOnClickListener( new DismissKeyboardListener(this) ); 

활동에 대한 키워드입니다. 그래서 조각에 있다면 getActivity ()와 같이 사용하십시오.

--- 엄청나게 도와 주면 ... --- Ralph를 응원합니다 ---


1

이것은 fje의 답변 중 약간 수정 된 버전으로 대부분 완벽하게 작동했습니다.

이 버전은 ACTION_DOWN을 사용하므로 스크롤 동작을 수행하면 키보드도 닫힙니다. 또한 다른 EditText를 클릭하지 않으면 이벤트가 전파되지 않습니다. 즉, 다른 클릭 가능 텍스트에서도 EditText 외부의 아무 곳이나 클릭하면 키보드가 닫힙니다.

@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
    if(ev.getAction() == MotionEvent.ACTION_DOWN)
    {
        final View view = getCurrentFocus();

        if(view != null)
        {
            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view))
            {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y))
                {
                    super.dispatchTouchEvent(ev);
                    return true;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText)
            {
                super.dispatchTouchEvent(ev);
                return true;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

여기 뭔가가 보이지 않습니다. viewviewTmp에 모두를 할당 getCurrentFocus()하므로 항상 같은 값이됩니다.
Andy Dennie

1

나는 이렇게했다 :

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
   View view = getCurrentFocus();
   if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
            int scrcoords[] = new int[2];
            view.getLocationOnScreen(scrcoords);
            float x = ev.getRawX() + view.getLeft() - scrcoords[0];
            float y = ev.getRawY() + view.getTop() - scrcoords[1];
            if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
                hideKeyboard(this);
        }
    return super.dispatchTouchEvent(ev);
}

키보드 코드 숨기기 :

public static void hideKeyboard(Activity act) {
    if(act!=null)
      ((InputMethodManager)act.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((act.getWindow().getDecorView().getApplicationWindowToken()), 0);
  }

끝난

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.