ImeOptions의 완료 버튼 클릭을 어떻게 처리합니까?


185

EditText사용자가 EditText를 클릭 할 때 키보드에 완료 버튼을 표시 할 수 있도록 다음 속성을 설정 하는 위치가 있습니다.

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

사용자가 화면 키보드에서 완료 버튼을 클릭하면 (입력 완료) RadioButton상태 를 변경하고 싶습니다 .

화면 키보드에서 완료된 버튼을 어떻게 추적합니까?

소프트웨어 키보드의 오른쪽 하단 '완료'버튼을 보여주는 스크린 샷


1
OnKeyboardActionListener 일 수 있습니다. 코드 예제가 필요합니까 ??
d-man

답변:


210

나는 Roberts와 chirags 답변의 조합으로 끝났습니다.

((EditText)findViewById(R.id.search_field)).setOnEditorActionListener(
        new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        // Identifier of the action. This will be either the identifier you supplied,
        // or EditorInfo.IME_NULL if being called due to the enter key being pressed.
        if (actionId == EditorInfo.IME_ACTION_SEARCH
                || actionId == EditorInfo.IME_ACTION_DONE
                || event.getAction() == KeyEvent.ACTION_DOWN
                && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
            onSearchAction(v);
            return true;
        }
        // Return true if you have consumed the action, else false.
        return false;
    }
});

업데이트 : 위의 코드는 때로는 콜백을 두 번 활성화합니다. 대신 Google 채팅 클라이언트에서 얻은 다음 코드를 선택했습니다.

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    // If triggered by an enter key, this is the event; otherwise, this is null.
    if (event != null) {
        // if shift key is down, then we want to insert the '\n' char in the TextView;
        // otherwise, the default action is to send the message.
        if (!event.isShiftPressed()) {
            if (isPreparedForSending()) {
                confirmSendMessageIfNeeded();
            }
            return true;
        }
        return false;
    }

    if (isPreparedForSending()) {
        confirmSendMessageIfNeeded();
    }
    return true;
}

4
방금 IME_ACTION_DONE을 찾고 트리거되지 않은 것에 놀랐습니다. ACTION_DOWN 및 KEYCODE_ENTER도 찾은 후 마침내 onEditorAction ()이 트리거되었습니다. 내장 키보드에는 아무런 차이가 없으므로 (Enter 키가 강조 표시 될 것으로 예상) EditText XML 레이아웃에 android : imeOptions = "actionSend"를 사용하는 것이 무엇인지 궁금합니다.
누군가 어딘가에

왜이 대답이 받아 들여지지 않습니까? 몇 가지 경우에 실패합니까 ??
Archie.bpgc

1
developer.android.com/reference/android/widget/… ( '이벤트'에 대한 설명도 동일합니다.)
Darpan

2
두 번째 솔루션도 두 번 트리거됩니다.
Bagusflyer

1
isPreparedForSending()두 번째 방법 은 무엇 이며 왜 반환 true합니까?
CoolMind

122

이것을 시도하십시오. 필요한 것에서 작동해야합니다.


editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

10
HTC Evo에서는 작동하지 않습니다. 내가 이해할 수있는 한 HTC는 imeOptions를 무시하는 자체 소프트 키보드를 구현했습니다.
Dan

이것으로 충분합니다 (허용 된 답변에서와 같이 이벤트 조치 또는 키 코드를 볼 필요가 없습니다). Nexus 및 Samsung 테스트 기기에서 작동합니다.
Jonik

안전을 위해 코드와 뷰의 동작이 일치하는지 확인하십시오 <EditText android:imeOptions="actionDone" android:inputType="text"/>
bh_earth0

40
<EditText android:imeOptions="actionDone"
          android:inputType="text"/>

Java 코드는 다음과 같습니다.

edittext.setOnEditorActionListener(new OnEditorActionListener() { 
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            Log.i(TAG,"Here you can write the code");
            return true;
        }    
        return false;
    }
});

if 절에서 true를 반환하여 처리했다고 말해야합니다.
Tim Kist

26

나는이 질문이 오래되었다는 것을 알고 있지만 나에게 도움이 된 것을 지적하고 싶다.

Android 개발자 웹 사이트 (아래 참조) 의 샘플 코드를 사용해 보았지만 작동하지 않았습니다. 그래서 EditorInfo 클래스를 확인하고 IME_ACTION_SEND 정수 값이 다음과 같이 지정되었음을 깨달았습니다.0x00000004 .

Android 개발자의 샘플 코드 :

editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextEmail
        .setOnEditorActionListener(new OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId,
                    KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    /* handle action here */
                    handled = true;
                }
                return handled;
            }
        });

그래서 정수 값을 res/values/integers.xml파일에 추가했습니다 .

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="send">0x00000004</integer>
</resources>

그런 다음 레이아웃 파일 res/layouts/activity_home.xml을 다음과 같이 편집했습니다.

<EditText android:id="@+id/editTextEmail"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:imeActionId="@integer/send"
  android:imeActionLabel="@+string/send_label"
  android:imeOptions="actionSend"
  android:inputType="textEmailAddress"/>

그런 다음 샘플 코드가 작동했습니다.


17

OnKeyListener를 설정하고 완료 버튼을 수신하는 방법에 대한 자세한 내용.

먼저 클래스의 구현 섹션에 OnKeyListener를 추가하십시오. 그런 다음 OnKeyListener 인터페이스에 정의 된 함수를 추가하십시오.

/*
 * Respond to soft keyboard events, look for the DONE press on the password field.
 */
public boolean onKey(View v, int keyCode, KeyEvent event)
{
    if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
        (keyCode == KeyEvent.KEYCODE_ENTER))
    {
        // Done pressed!  Do something here.
    }
    // Returning false allows other listeners to react to the press.
    return false;
}

EditText 객체가 주어지면 :

EditText textField = (EditText)findViewById(R.id.MyEditText);
textField.setOnKeyListener(this);

2
소프트 키 이벤트에 대해 OnKeyListener가 더 이상 실행되지 않기 때문에 API 레벨 17 이상을 대상으로하는 애플리케이션에서는 더 이상 작동하지 않습니다. developer.android.com/reference/android/text/method/…
jjb

그들은 지금 대안을 제안합니까?
Robert Hawkey

2
setOnEditorActionListener를 사용하여 EditorInfo.IME_ACTION_DONE을 찾는 것으로 전환했습니다.
jjb

onKey는 false가 아닌 true를 반환해야합니다.
ralphgabb

16

대부분의 사람들이이 질문에 직접 대답했지만, 그 개념에 대해 더 자세히 설명하고 싶었습니다. 먼저 기본 로그인 활동을 만들 때 IME에 주목했습니다. 다음과 같은 코드가 생성되었습니다.

<EditText
  android:id="@+id/password"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/prompt_password"
  android:imeActionId="@+id/login"
  android:imeActionLabel="@string/action_sign_in_short"
  android:imeOptions="actionUnspecified"
  android:inputType="textPassword"
  android:maxLines="1"
  android:singleLine="true"/>

inputType 속성에 대해 잘 알고 있어야합니다. 이것은 이메일 주소, 비밀번호 또는 전화 번호와 같이 예상되는 텍스트 유형을 Android에 알려줍니다. 가능한 값의 전체 목록은 여기 에서 찾을 수 있습니다 .

그러나 그것이 imeOptions="actionUnspecified"그 목적을 이해하지 못한 속성이었습니다 . Android를 사용하면를 사용하여 텍스트를 선택할 때 화면 하단에서 팝업되는 키보드와 상호 작용할 수 있습니다 InputMethodManager. 키보드의 하단 모서리에는 현재 텍스트 필드에 따라 일반적으로 "다음"또는 "완료"버튼이 있습니다. Android에서는을 사용하여이를 사용자 지정할 수 있습니다 android:imeOptions. "보내기"버튼 또는 "다음"버튼을 지정할 수 있습니다. 전체 목록은 여기 에서 찾을 수 있습니다 .

그런 다음 요소에 TextView.OnEditorActionListener대해 를 정의하여 작업 단추의 누름을들을 수 있습니다 EditText. 귀하의 예에서와 같이 :

editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

이제 내 예제에서 나는 android:imeOptions="actionUnspecified"속성을 가졌다 . 사용자가 Enter 키를 누를 때 로그인을 시도 할 때 유용합니다. 활동에서이 태그를 감지 한 후 로그인을 시도 할 수 있습니다.

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

6

Kotlin의 chikka.anddevAlex Cohn 덕분에 다음 과 같습니다.

text.setOnEditorActionListener { v, actionId, event ->
    if (actionId == EditorInfo.IME_ACTION_DONE ||
        event?.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER) {
        doSomething()
        true
    } else {
        false
    }
}

여기서 EnterEditorInfo.IME_NULL대신 확인하기 때문에 키를 확인합니다.IME_ACTION_DONE .

Android imeOptions = "actionDone"작동하지 않음 도 참조하십시오 . 에 추가 android:singleLine="true"하십시오 EditText.


6

코 틀린 솔루션

Kotlin에서 처리하는 기본 방법은 다음과 같습니다.

edittext.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        callback.invoke()
        true
    }
    false
}

코 틀린 확장

이것을 사용 edittext.onDone{/*action*/}하여 메인 코드를 호출 하십시오. 코드를 훨씬 더 읽기 쉽고 유지 보수 가능하게 만듭니다.

fun EditText.onDone(callback: () -> Unit) {
    setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            callback.invoke()
            true
        }
        false
    }
}

이 옵션을 편집 텍스트에 추가하는 것을 잊지 마십시오

<EditText ...
    android:imeOptions="actionDone"
    android:inputType="text"/>

inputType="textMultiLine"지원 이 필요하면 이 게시물을 읽으십시오


1
좋은 답변, 공유 주셔서 감사합니다! 그래도의 반환 값에 대해 보푸라기 경고가 계속 나타납니다 setOnEditorActionListener. 어쩌면 로컬 구성 설정의 문제 일 수도 있지만 실제로 는 linter가 실제로 else"block"과 리스너의 return 문으로 "true"를 허용하기 위해 분기 를 추가하기를 원합니다 if.
dbm

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