2013-02-20 66 views
27

如何攔截這類事件?Android攔截在editText上粘貼 copy cut

我需要添加當用戶試圖粘貼一些文本到我EditText我知道我可以使用TextWatcher但這個入口點不是爲我好監守我只需要粘貼的情況下攔截用戶每次一些邏輯,而不是按我的EditText

+0

好挑戰。看看我的答案。 – 2013-02-20 13:45:49

回答

62

似乎沒有太多的你可以使用API​​做的事:android paste event

Source reading to the rescue!

我挖成TextViewEditText的Android的源代碼是TextView),並發現用於提供剪切/複製/粘貼選項的菜單只是一個修改的ContextMenusource)。

對於普通的上下文菜單,視圖必須創建菜單(source),然後在回調方法(source)中處理交互。

因爲處理方法是public,我們可以通過擴展EditText來簡單地掛鉤它,並覆蓋方法以對不同的動作作出反應。下面是一個例子的實現:

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

現在,當用戶使用剪切/複製/粘貼,一個Toast顯示(當然你可以做其他的事情,太)。

的妙處是,這個工程下來到Android 1.5,你不需要重新創建上下文菜單(如建議在上面的鏈接的問題),這將保持在恆定的樣子平臺(例如HTC Sense)。

+0

我得到**不能實例化類沒有空的構造函數**錯誤是什麼解決方案? – 2014-07-11 11:50:57

+0

好吧,類沒有空的構造函數。你必須傳遞一個'Context'的實例(如果你的代碼在一個Activity中,你可以傳遞'this')。 – 2014-07-11 16:32:43

+0

用偵聽器擴展您的解決方案,以便它可以用作即插即用組件。要點https://gist.github.com/guillermomuntaner/82491cbf0c88dec560a5 – GuillermoMP 2016-01-17 21:12:51

0

雖然不是100%可靠,但有一種更簡單的方法。

添加TextChangedListener到您的編輯框:

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) { 

    } 
}); 

如果超過2個字符文本的變化,你可以假定它粘貼(一些表情符號佔用兩個字符)。

當用戶粘貼1或2個字符時,它當然不會檢測粘貼,並且如果文本中的更改由其他內容觸發,它將錯誤地報告粘貼。

但是對於大多數目的而言,它可以完成工作。