2012-07-02 29 views
23

Tôi có văn bản chỉnh sửa có chức năng như một hộp tìm kiếm trong ứng dụng của tôi. Trong Jelly Bean trên Nexus 7 của tôi khi tôi gõ một cái gì đó vào hộp văn bản mà tôi đang nghe và nhấn vào KeyEvent = null và ActionId = 0 được chuyển vào phương thức onEditorAction(). Đã có người khác gặp phải điều này? Tôi nghĩ rằng nó có thể là một lỗi.null keyevent và actionid = 0 trong onEditorAction() (Jelly Bean/Nexus 7)

Trong câu lệnh if thứ hai bên dưới, tôi nhận được con trỏ rỗng vì actionId = 0 và KeyEvent = null;

// Search field logic. 
@Override 
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
    Log.d(TAG, "onEditorAction"); 
    if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) 
     return false; 
    if (actionId == EditorInfo.IME_ACTION_SEARCH 
      || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { 
       .....Do some stuff(); 
    } 
} 
+0

Vui lòng sử dụng thẻ 'android-edittext' thay vì' edittext' :) –

+3

'sự kiện' chắc chắn đôi khi là' null', quay lại ít nhất là Honeycomb. Đây là một dự án mẫu cho thấy cách tôi sử dụng 'onEditorAction()': https://github.com/commonsguy/cw-omnibus/tree/master/ActionBar/ActionBarDemo – CommonsWare

+0

@CommonsWare Tôi đã thử ví dụ của bạn: –

Trả lời

38

Đã kết thúc bằng cách thêm kiểm tra không chính xác cho KeyEvent. Nhờ commonsware cho việc chỉ ra điều này xảy ra trên 3.0+. Có vẻ giống như một giải pháp sau đó là một giải pháp, nhưng nó hoạt động.

// Search field logic. 
@Override 
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
    Log.d(TAG, "onEditorAction"); 
    if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { 
     return false; 
    } else if (actionId == EditorInfo.IME_ACTION_SEARCH 
     || event == null 
     || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { 
       .....Do some stuff(); 
    } 
} 
+6

cho ** [onEditorAction (TextView v, int actionId, sự kiện KeyEvent)] (http://developer.android.com/intl/es/reference/android/widget/TextView.OnEditorActionListener.html#onEditorAction (android.widget. TextView,% 20int,% 20android.view.KeyEvent)) **, 'actionId' có thể là ** [EditorInfo.IME_NULL] (http://developer.android.com/intl/es/reference/android/view/inputmethod /EditorInfo.html#IME_NULL)**, có nghĩa là * phím enter được nhấn *. –

+0

Tuyệt vời! Cảm ơn. Trong số nhiều giải pháp về các câu hỏi khác nhau, câu hỏi này hoạt động rất tốt, ngay cả đối với Android M. –

+1

Thực ra, EditorInfo.IME_ACTION_DONE là phím Enter/Done, ít nhất trên Android 4.4.2. – FractalBob

1

Điều đáng lưu ý là bạn có thể nhận được nhiều sự kiện cho nhấp chuột vào Enter (tùy thuộc vào phiên bản Android). Một cho KeyDown (KeyEvent.ACTION_DOWN), một cho KeyUp (KeyEvent.ACTION_UP). Khi tôi quên kiểm tra xem tôi có vô tình bắt đầu hai cuộc gọi máy chủ cho cùng một hành động hay không.

searchBox.setOnEditorActionListener(new OnEditorActionListener() { 
// enter key in search box triggers search 
@Override 
public boolean onEditorAction(TextView v, int actionId, 
     KeyEvent event) { 
    if ((event != null && event.getAction() == KeyEvent.ACTION_UP) || event==null) { 
     onSearchButtonClicked(); 
    } 
    return true; 
} 
}); 
+0

Tôi tự hỏi lý do này có. Đối với tôi điều này thực sự gây phiền nhiễu. Nút enter đại diện cho sự kiện nhập, và điều này chắc chắn là một trong những phím lâu đời nhất và quan trọng nhất trên mỗi thiết bị giống như máy tính với giao diện con người. Vì vậy, có một lý do, tại sao nó có vẻ bị mất kể từ Android 3.0? Khi tôi gặp sự cố này, tôi muốn biết, có gì sai với EditorInfo.IME_ACTION_DONE? – icbytes

3

Bên cạnh KeyEvent.ACTION_UP chúng tôi cũng cần chụp KeyEvent.ACTION_DOWN. Trừ khi KeyEvent.ACTION_UP sẽ không bao giờ được chuyển đến EditText vì vậy, onEditorAction của chúng tôi sẽ không hoạt động. Ví dụ:

@Override 
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
    final boolean isEnterEvent = event != null 
      && event.getKeyCode() == KeyEvent.KEYCODE_ENTER; 
    final boolean isEnterUpEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_UP; 
    final boolean isEnterDownEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_DOWN; 

    if (actionId == EditorInfo.IME_ACTION_DONE || isEnterUpEvent) { 
     // Do your action here 
     performLogin(); 
     return true; 
    } else if (isEnterDownEvent) { 
     // Capture this event to receive ACTION_UP 
     return true; 
    } else { 
     // We do not care on other actions 
     return false; 
    } 
} 

Bạn phải thay thế EditorInfo.IME_ACTION_DONE để sửa phiên bản của EditorInfo.IME_ACTION_ theo android:imeOptions="actionNext"

4

tôi thấy rằng "hành vi lỗi giống như" tôi là do imeActionLabel điều phức tạp. Tôi chỉ sử dụng nó bởi vì nó đã được đề cập trong các Text Fields Guide như một cách để có một nhãn chìa khóa trở lại tùy chỉnh. Dưới đây là kết quả kiểm tra của tôi trong Lollipop,

Trường hợp 1: mặc định, trở về chính biểu tượng = đóng góc khung

<EditText 
    android:singleLine="true" 
    android:inputType="textUri"/> 

onEditorAction được gọi một lần.

  • KeyEvent = null, actionId = 5 = EditorInfo.IME_ACTION_NEXT
    • nếu trở thành sự thật, con trỏ vẫn trong EditText, bàn phím mở
    • nếu trở lại sai, con trỏ di chuyển đến tiếp theo có thể đặt tiêu, bàn phím mở nếu cần thiết

Trường hợp 2:imeOptions, trở về biểu tượng key = dấu kiểm

<EditText 
    android:singleLine="true" 
    android:inputType="textUri" 
    android:imeOptions="actionDone"/> 

onEditorAction được gọi một lần.

  • KeyEvent = null, actionId = 6 = EditorInfo.IME_ACTION_DONE
    • nếu trở thành sự thật, con trỏ vẫn trong EditText, bàn phím mở
    • nếu trở lại sai, con trỏ vẫn trong EditText, bàn phím đóng

Trường hợp 3:imeActionLabel, trở về chính biểu tượng = "URdone"

<EditText 
    android:singleLine="true" 
    android:inputType="textUri" 
    android:imeOptions="actionDone" 
    android:imeActionLabel="URdone"/> 

onEditorAction có thể được gọi nhiều hơn một lần.

  • KeyEvent = null, actionId = 0

    • nếu trở thành sự thật, con trỏ vẫn trong EditText, bàn phím mở, onEditorAction KHÔNG gọi lần thứ hai
    • nếu trả về false, onEditorAction được gọi là thời gian SECOND:
  • KeyEvent = KeyEvent.ACTION_DOWN, actionId = 0

    • nếu trả về false, con trỏ di chuyển đến tiếp theo đặt tiêu điểm, bàn phím mở nếu cần thiết, onEditorAction KHÔNG gọi lần thứ ba
    • nếu trở thành sự thật, onEditorAction được gọi là thời gian BA :
  • KeyEvent = KeyEvent.ACTION_UP, actionId = 0

    • nếu trở thành sự thật, con trỏ vẫn trong EditText, bàn phím mở
    • nếu trả về false, con trỏ di chuyển đến tiếp theo đặt tiêu điểm, bàn phím mở nếu cần thiết

GHI CHÚ:

Tôi không chắc liệu actionId = 0 có phải là từ EditorInfo.IME_ACTION_UNSPECIFIED hoặc EditorInfo.IME_NULL.

Nếu tiêu điểm tiếp theo là không thể chỉnh sửa, biểu tượng chìa khóa trả về sẽ trở thành mũi tên chỉ sang trái.

Bạn cũng có thể sử dụng setOnFocusChangeListener để ghi đè onFocusChange, sẽ được gọi theo hành vi con trỏ ở trên.

Các vấn đề liên quan