Android拦截在editText上粘贴\ copy\cut

and*_*dev 34 android textview textwatcher android-edittext

我该如何拦截这类事件?

我需要添加一些逻辑,当用户试图粘贴一些文本到我EditText知道我可以使用TextWatcher但这个入口点对我不好,因为我只需要拦截粘贴的情况下,而不是每次用户按我的EditText,

Luk*_*uth 74

似乎使用API​​可以做的事情不多:android粘贴事件

来源阅读救援!

我挖成的Android的源TextView(EditText是一个TextView具有一些不同的配置),并且发现了用于提供剪切/复制/粘贴选项的菜单只是一个修饰ContextMenu(来源).

对于普通的上下文菜单,View必须创建菜单(),然后在回调方法()中处理交互.

因为处理方法是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当用户使用剪切/复制/粘贴时,Toast会显示一个(当然,您也可以执行其他操作).

巧妙的是,这可以解决Android 1.5的问题,你不需要重新创建上下文菜单(如上面链接的问题所示),这将保持平台的恒定外观(例如使用HTC Sense ).

  • 通过侦听器扩展了您的解决方案,因此可以用作即插即用组件。要点https://gist.github.com/guillermomuntaner/82491cbf0c88dec560a5 (2认同)

len*_*ooh 9

有一种更简单的方法,虽然不是 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) {
               
  }
});
Run Code Online (Sandbox Code Playgroud)

如果文本更改超过 2 个字符,您可以认为它已粘贴(某些表情符号占用两个字符)。

当然,当用户粘贴 1 或 2 个字符时,它不会检测到粘贴,如果文本的变化是由其他东西触发的,它会错误地报告粘贴。

但在大多数情况下,它可以完成工作

  • tiagocarvalho92:是的,描述中写了。 (2认同)