Làm cách nào để xử lý nhấp vào nút thực hiện của ImeOptions?


185

Tôi đang có một EditTextnơi tôi đang đặt thuộc tính sau để tôi có thể hiển thị nút thực hiện trên bàn phím khi người dùng nhấp vào EditText.

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

Khi người dùng nhấp vào nút thực hiện trên bàn phím màn hình (nhập xong) tôi muốn thay đổi RadioButtontrạng thái.

Làm thế nào tôi có thể theo dõi nút thực hiện khi nó được nhấn từ bàn phím màn hình?

Ảnh chụp màn hình hiển thị nút 'xong' phía dưới bên phải trên bàn phím phần mềm


1
có thể OnPalActionListener giúp tôi bất kỳ ví dụ mã nào ??
d-man

Câu trả lời:


210

Tôi đã kết thúc với sự kết hợp của câu trả lời của Roberts và 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;
    }
});

Cập nhật: Mã trên đôi khi sẽ kích hoạt gọi lại hai lần. Thay vào đó, tôi đã chọn mã sau đây mà tôi nhận được từ các ứng dụng trò chuyện của 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
Tôi chỉ tìm IME_ACTION_DONE và tôi đã ngạc nhiên rằng nó không kích hoạt. Sau khi tôi cũng tìm kiếm ACTION_DOWN và KEYCODE_ENTER, cuối cùng nó đã kích hoạt onEditorAction (). Vì tôi thấy không có sự khác biệt nào trong bàn phím tích hợp (tôi dự kiến ​​phím Enter sẽ được tô sáng) Tôi tự hỏi ý nghĩa của việc sử dụng android: imeOptions = "actionSend" cho bố cục EditText XML là gì.
Ai đó ở đâu đó

Tại sao câu trả lời này không được chấp nhận. Điều này có thất bại trong vài trường hợp không ??
Archie.bpgc

1
developer.android.com/reference/android/widget/ (Mô tả về những gì một 'sự kiện' được khẳng định giống nhau.)
Darpan

2
Giải pháp thứ hai cũng được kích hoạt hai lần.
Bagusflyer

1
Là gì isPreparedForSending()và tại sao phương thức thứ hai trả về true?
CoolMind

122

Hãy thử điều này, nó sẽ hoạt động cho những gì bạn cần:


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
Điều này không hoạt động cho HTC Evo. Theo như tôi có thể hiểu, HTC đã triển khai bàn phím mềm của riêng họ mà bỏ qua các imeOptions.
Dan

Điều này đủ (không cần phải xem hành động sự kiện hoặc mã khóa, như trong câu trả lời được chấp nhận); hoạt động trên các thiết bị thử nghiệm Nexus và Samsung của tôi.
Jonik

để đảm bảo an toàn, hãy đảm bảo rằng hành động trong mã và chế độ xem khớp với nhau <EditText android:imeOptions="actionDone" android:inputType="text"/>
bh_earth0

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

Mã Java là:

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;
    }
});

Bạn nên trả về true trong mệnh đề if để nói rằng bạn đã xử lý nó
Tim Kist

26

Tôi biết câu hỏi này đã cũ, nhưng tôi muốn chỉ ra những gì làm việc cho tôi.

Tôi đã thử sử dụng mã mẫu từ trang web của Nhà phát triển Android (hiển thị bên dưới), nhưng nó không hoạt động. Vì vậy, tôi đã kiểm tra lớp EditorInfo và tôi nhận ra rằng giá trị số nguyên IME_ACTION_SEND được chỉ định là 0x00000004.

Mã mẫu từ Nhà phát triển 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;
            }
        });

Vì vậy, tôi đã thêm giá trị số nguyên vào res/values/integers.xmltập tin của mình .

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

Sau đó, tôi chỉnh sửa tập tin bố cục của mình res/layouts/activity_home.xmlnhư sau

<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"/>

Và sau đó, mã mẫu làm việc.


17

Thêm chi tiết về cách đặt OnKeyListener và nghe nó cho nút Xong.

Đầu tiên thêm OnKeyListener vào phần thực hiện của lớp của bạn. Sau đó thêm chức năng được xác định trong giao diện 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;
}

Đưa ra một đối tượng EditText:

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

2
Điều này không hoạt động nữa đối với các ứng dụng nhắm mục tiêu API cấp 17+, vì OnKeyListener của bạn không còn được kích hoạt cho các sự kiện phím mềm: developer.android.com/reference/android/text/method/iêu
jjb

Họ có đề xuất một sự thay thế bây giờ?
Robert Hawkey

2
Tôi đã chuyển sang sử dụng setOnEditorActionListener để tìm EditorInfo.IME_ACTION_DONE, có vẻ như hoạt động tốt.
jjb 16/12/13

onKey sẽ trả về true, không false.
ralphgabb 27/1/2015

16

Trong khi hầu hết mọi người đã trả lời câu hỏi trực tiếp, tôi muốn giải thích thêm về khái niệm đằng sau nó. Đầu tiên, tôi bị thu hút bởi sự chú ý của IME khi tôi tạo một Hoạt động đăng nhập mặc định. Nó tạo ra một số mã cho tôi bao gồm:

<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"/>

Bạn đã quen thuộc với thuộc tính inputType. Điều này chỉ thông báo cho Android loại văn bản dự kiến ​​như địa chỉ email, mật khẩu hoặc số điện thoại. Danh sách đầy đủ các giá trị có thể có thể được tìm thấy ở đây .

Tuy nhiên, đó là thuộc tính imeOptions="actionUnspecified"mà tôi không hiểu mục đích của nó. Android cho phép bạn tương tác với bàn phím bật lên từ dưới màn hình khi văn bản được chọn bằng cách sử dụng InputMethodManager. Ở góc dưới cùng của bàn phím, có một nút, thông thường là "Tiếp theo" hoặc "Xong", tùy thuộc vào trường văn bản hiện tại. Android cho phép bạn tùy chỉnh điều này bằng cách sử dụng android:imeOptions. Bạn có thể chỉ định nút "Gửi" hoặc nút "Tiếp theo". Danh sách đầy đủ có thể được tìm thấy ở đây .

Cùng với đó, sau đó bạn có thể nghe cho máy ép vào nút hành động bằng cách định nghĩa một TextView.OnEditorActionListenercho EditTextphần tử. Như trong ví dụ của bạn:

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;
    } 
});

Bây giờ trong ví dụ của tôi, tôi đã có android:imeOptions="actionUnspecified"thuộc tính. Điều này hữu ích khi bạn muốn thử đăng nhập người dùng khi họ nhấn phím enter. Trong Hoạt động của bạn, bạn có thể phát hiện thẻ này và sau đó thử đăng nhập:

    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

Cảm ơn chikka.anddevAlex Cohn trong Kotlin, đó là:

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
    }
}

Ở đây tôi kiểm tra Enterchìa khóa, bởi vì nó trả về EditorInfo.IME_NULLthay vì IME_ACTION_DONE.

Xem thêm Android imeOptions = "actionDone" không hoạt động . Thêm android:singleLine="true"vào EditText.


6

Giải pháp Kotlin

Cách cơ bản để xử lý nó trong Kotlin là:

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

Gia hạn Kotlin

Sử dụng điều này để chỉ gọi edittext.onDone{/*action*/}trong mã chính của bạn. Làm cho mã của bạn dễ đọc hơn và dễ bảo trì hơn

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

Đừng quên thêm các tùy chọn này vào edittext của bạn

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

Nếu bạn cần inputType="textMultiLine"hỗ trợ, hãy đọc bài viết này


1
Câu trả lời tuyệt vời, cảm ơn vì đã chia sẻ! Tôi dường như tiếp tục nhận được một cảnh báo lint liên quan đến giá trị trả lại của setOnEditorActionListener, mặc dù. Có thể đó chỉ là vấn đề của cài đặt cấu hình cục bộ, nhưng người nói dối của tôi thực sự, thực sự muốn tôi thêm một elsechi nhánh để chấp nhận "đúng" như một tuyên bố trả lại của người nghe (trái ngược với if-block).
dbm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.