2011-07-08 32 views
7

Tôi có một số EditText. Bây giờ tôi muốn nhận tất cả các thay đổi mà người dùng thực hiện cho số này EditText và làm việc với chúng trước khi chèn chúng vào EditText theo cách thủ công. Tôi không muốn người dùng thay đổi trực tiếp văn bản trong số EditText. Điều này chỉ nên được thực hiện bằng mã của tôi (ví dụ: bằng cách sử dụng replace() hoặc setText()).Cách sử dụng InputConnectionWrapper?

Tôi đã tìm kiếm một chút và tìm thấy một lớp học thú vị có tên là InputConnectionWrapper. Theo javadoc nó sẽ hoạt động như một proxy cho một InputConnection. Vì vậy, tôi subclassed nó như thế này:

private class EditTextInputConnection extends InputConnectionWrapper { 

    public EditTextInputConnection(InputConnection target, boolean mutable) { 
     super(target, mutable); 
    } 

    @Override 
    public boolean commitText(CharSequence text, int newCursorPosition) { 
        // some code which takes the input and manipulates it and calls editText.getText().replace() afterwards 
     return true; 
    } 

} 

Để khởi tạo wrapper tôi ghi đè lên các phương pháp sau đây trong EditText -subclass tôi:

public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 
    InputConnection con = super.onCreateInputConnection(outAttrs); 
    EditTextInputConnection connectionWrapper = new EditTextInputConnection(con, true); 
    return connectionWrapper; 
} 

Tuy nhiên, commitText() không bao giờ được gọi. Số gọi onCreateInputConnection() được gọi và hàm tạo của EditTextInputConnection cũng vậy, nhưng không bao giờ commitText(), khi cần nhập một số văn bản vào trường này, nó sẽ là đủ. Ít nhất, đó là cách tôi hiểu cách sử dụng của InputConnectionWrapper. Hoặc là tôi sai?

Chỉnh sửa: " ' Dường như, đó commitText() chỉ được gọi cho các ký tự đặc biệt như'" vv Theo tôi được biết các mã nguồn Android cho tất cả các nhân vật khác InputConnectionWrapper.sendKeyEvent() nên được gọi, nhưng đó không phải là trường hợp .. Tôi hoàn toàn bị mắc kẹt vào thời điểm này. Tôi đã thử EditText.onKeyPreIme(), nhưng điều này chỉ hoạt động trên bàn phím phần cứng. Vì vậy, đó là không có thay thế ... Tôi không thực sự hiểu, tại sao Android xử lý bàn phím mềm khác với bàn phím phần cứng. EditText.onTextChanged() cũng được kích hoạt khi người dùng không nhập, vì vậy đây cũng không phải là những gì tôi đang tìm kiếm.

Trả lời

5

Nó bật ra, rằng việc sử dụng ở trên của InputConnectionWrapper là hoàn toàn chính xác. Tuy nhiên, commitText() không bao giờ được gọi (ngoại trừ trường hợp đặc biệt), vì có các phương pháp khác, được sử dụng trong khi nhập. Đây chủ yếu là setComposingText()sendKeyEvent(). Tuy nhiên, cũng rất quan trọng để ghi đè các phương pháp ít khi được sử dụng như deleteSurroundingText() hoặc commitText() để đảm bảo bắt được mọi đầu vào của người dùng.

+1

Điều này không ngăn người dùng sao chép văn bản ngẫu nhiên vào EditText, nhưng hoạt động với mọi thứ khác. – Alexey

+0

@ Alexey Đúng vậy, điểm tốt. – ubuntudroid

+0

@ubuntudroid Xin chào, bạn có biết phương pháp nào cần được ghi đè để nắm bắt tất cả các yếu tố đầu vào không? Bao gồm dán bản sao. –

1

Blundell được đề xuất trong cuộc trò chuyện mà bạn sử dụng TextWatcher. Kiểm tra xem điều này có giúp bạn không.

+0

Sự cố với Trình xem văn bản là, tôi không thể xác định nguồn đầu vào ở đó (tức là đầu vào hoặc đầu vào bàn phím trực tiếp từ mã của tôi). Nó cũng sẽ được thông báo, nếu tôi thay đổi văn bản bằng EditText.getText(). Replace() hoặc EditText.setText(), tôi giả sử. – ubuntudroid

+0

Tôi không chắc chắn, bạn đã thử nghiệm nó chưa? –

+0

Nó sẽ được như thế này, như getText(). Replace()/insert() hoạt động trực tiếp trên Editable phía sau EditText. Vì vậy, TextWatcher theo dõi các thay đổi của Editable sẽ được thông báo về bất kỳ thay đổi nào của Editable. Tôi hiện đang làm việc trên một giải pháp khác kết hợp một lớp con của các phương thức có thể chỉnh sửa và đặc biệt để truy cập nó từ mã và các phương thức ghi đè để chèn() và thay thế(). Sẽ đăng các phát hiện của tôi ở đây một khi nó được thực hiện. – ubuntudroid

0

Sử dụng Trình xem văn bản, ngắt kết nối khi bạn sửa đổi văn bản và kết nối lại khi hoàn tất. Bằng cách này, bạn sẽ không kích hoạt các cuộc gọi vô hạn.