41

この種のイベントを傍受するにはどうすればよいですか?

ユーザーがテキストを貼り付けようとするときにロジックを追加する必要がありますが、EditText使用できることはわかってTextWatcherいますが、貼り付けの場合にのみ傍受する必要があり、ユーザーが my を押すたびにではなくEditText

4

2 に答える 2

93

APIを使用してできることはあまりないようです:android paste event

救助のためのソース読み取り!

TextView(EditTextは構成が異なる )の Android ソースを掘り下げたTextViewところ、切り取り/コピー/貼り付けオプションを提供するために使用されるメニューは、単に変更されたContextMenu( source ) であることがわかりました。

通常のコンテキスト メニューと同様に、View はメニューを作成し ( 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 を使用)。 )。

于 2013-02-20T13:44:50.967 に答える
8

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 文字以上変更されている場合は、貼り付けられたと見なすことができます (一部のスマイリーは 2 文字を使用します)。

もちろん、ユーザーが 1 文字または 2 文字を貼り付けた場合は貼り付けを検出しません。また、テキストの変更が他の何かによってトリガーされた場合、貼り付けを誤って報告します。

しかし、ほとんどの目的で、それは仕事を成し遂げます

于 2016-04-06T17:35:16.400 に答える