2013-02-20 27 views
27

Tôi có thể chặn loại sự kiện này bằng cách nào?Dán chặn Android copy cut trên editText

Tôi cần thêm một số logic khi người dùng cố gắng dán một số văn bản vào EditText tôi biết tôi có thể sử dụng TextWatcher nhưng điểm nhập này không tốt cho tôi vì tôi chỉ cần chặn trong trường hợp dán và không phải mỗi lần người dùng nhấn tôi EditText,

+0

Thách thức tốt. Nhìn vào câu trả lời của tôi. –

Trả lời

62

có vẻ không có nhiều bạn có thể làm bằng cách sử dụng các API: android paste event

Source reading to the rescue!

tôi đào vào Nguồn Android của TextView (EditText là một TextView với một số cấu hình khác nhau) và phát hiện ra rằng menu được sử dụng để cung cấp tùy chọn cắt/sao chép/dán chỉ là một sửa đổi ContextMenu (source).

Đối với menu ngữ cảnh thông thường, Chế độ xem phải tạo menu (source) và sau đó xử lý tương tác trong phương thức gọi lại (source).

Vì phương thức xử lý là public, chúng ta có thể chỉ cần móc vào nó bằng cách mở rộng EditText và ghi đè phương thức phản ứng trên các hành động khác nhau. Dưới đây là một ví dụ-thực hiện:

import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.EditText; 
import android.widget.Toast; 

/** 
* An EditText, which notifies when something was cut/copied/pasted inside it. 
* @author Lukas Knuth 
* @version 1.0 
*/ 
public class MonitoringEditText extends EditText { 

    private final Context context; 

    /* 
     Just the constructors to create a new EditText... 
    */ 
    public MonitoringEditText(Context context) { 
     super(context); 
     this.context = context; 
    } 

    public MonitoringEditText(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.context = context; 
    } 

    public MonitoringEditText(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     this.context = context; 
    } 

    /** 
    * <p>This is where the "magic" happens.</p> 
    * <p>The menu used to cut/copy/paste is a normal ContextMenu, which allows us to 
    * overwrite the consuming method and react on the different events.</p> 
    * @see <a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/widget/TextView.java#TextView.onTextContextMenuItem%28int%29">Original Implementation</a> 
    */ 
    @Override 
    public boolean onTextContextMenuItem(int id) { 
     // Do your thing: 
     boolean consumed = super.onTextContextMenuItem(id); 
     // React: 
     switch (id){ 
      case android.R.id.cut: 
       onTextCut(); 
       break; 
      case android.R.id.paste: 
       onTextPaste(); 
       break; 
      case android.R.id.copy: 
       onTextCopy(); 
     } 
     return consumed; 
    } 

    /** 
    * Text was cut from this EditText. 
    */ 
    public void onTextCut(){ 
     Toast.makeText(context, "Cut!", Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * Text was copied from this EditText. 
    */ 
    public void onTextCopy(){ 
     Toast.makeText(context, "Copy!", Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * Text was pasted into the EditText. 
    */ 
    public void onTextPaste(){ 
     Toast.makeText(context, "Paste!", Toast.LENGTH_SHORT).show(); 
    } 
} 

Bây giờ, khi người dùng sử dụng cut/copy/paste, một Toast được hiển thị (tất nhiên bạn có thể làm những việc khác nữa).

Điều gọn gàng là này hoạt động xuống Android 1.5 và bạn không cần phải tạo lại menu ngữ cảnh (như gợi ý trong câu hỏi liên kết ở trên), mà sẽ giữ giao diện liên tục của nền tảng (ví dụ với HTC Sense).

+0

tôi đã nhận ** không thể khởi tạo lớp không có constructor trống ** lỗi giải pháp của nó ??? –

+0

tốt, lớp không có hàm tạo rỗng. bạn phải chuyển nó một thể hiện của 'Context' (nếu mã của bạn đang ở trong một Activity, bạn có thể truyền nó' this'). –

+0

Mở rộng giải pháp của bạn với một người nghe để nó có thể được sử dụng như một thành phần plug & play. Gist https://gist.github.com/guillermomuntaner/82491cbf0c88dec560a5 – GuillermoMP

0

Có một cách đơn giản hơn nhiều, mặc dù không đáng tin cậy 100%.

Add TextChangedListener để editbox của bạn:

EditText et = (EditText) mView.findViewById(R.id.yourEditText); 
et.addTextChangedListener(new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
    if (count > 2) toast("text was pasted"); 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

    } 

    public void afterTextChanged(Editable s) { 

    } 
}); 

Nếu những thay đổi văn bản trong hơn 2 ký tự, bạn có thể giả định nó được dán (một số biểu tượng mặt cười mất hai ký tự).

Tất nhiên nó sẽ không phát hiện dán khi người dùng dán 1 hoặc 2 ký tự, và nó sẽ báo cáo sai khi dán nếu thay đổi trong văn bản được kích hoạt bởi cái gì khác.

Nhưng đối với hầu hết các mục đích, công việc được thực hiện.