android 如何捕捉粘贴事件从键盘剪贴板安卓?

ruoxqz4g  于 2022-12-16  发布在  Android
关注(0)|答案(1)|浏览(130)

我想捕捉编辑文本粘贴事件,与上下文菜单,我可以能够捕捉编辑文本粘贴事件如下。

etMobileNumber.customInsertionActionModeCallback = object : ActionMode.Callback {
            override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
                if(item?.itemId == android.R.id.paste){
               //log.d(“pastevent”)
                }

字符串
但是如果从键盘剪贴板粘贴的文本没有触发这个事件。如何触发这个事件?

jhdbpxl9

jhdbpxl91#

今天下午,当一位客户提出粘贴键盘操作没有将整个ClipData粘贴到我的EditTexts中时,我一直在为您的问题而挣扎。
我实现了一个2FA代码输入,每个6位数字有一个唯一的EditText,以适应设计的UI,所以我将每个EditText限制为1个字符。
但是键盘粘贴操作只将第一个字符设置到当前焦点EditText中,正如我在TextWatcher中看到的那样。
在调用堆栈中向上,我看到操作来自InputConnection。因此,我所做的是创建我自己的EditText,覆盖InputConnection onCreateInputConnection(EditorInfo)方法以返回我自己的InputConnectionWrapper,如下所示:

public interface OnTFACodePastedListener
{
    void onTFACodePasted(@NonNull final String code);
}

public final class TFADigitEditText extends TextInputEditText 
             implements OnTFACodePastedListener
{
    @NonNull
    @Override
    public InputConnection onCreateInputConnection(@NonNull EditorInfo outAttrs)
    {
        InputConnection ic = super.onCreateInputConnection(outAttrs);
        return new TFAInputConnectionWrapper(this, ic, false);
    }

    @Override
    public void onTFACodePasted(@NonNull String code)
    {
        // TODO: call void setText(CharSequence).
        // In my case, I had to dispatch it to all EditTexts holding the TFA digits 
        // through their parent custom view.
    }
}

public class TFAInputConnectionWrapper extends InputConnectionWrapper
{
    private final OnTFACodePastedListener mCodePastedListener;

    public TFAInputConnectionWrapper(@NonNull OnTFACodePastedListener pListener, 
                                     InputConnection target, boolean mutable)
    {
        super(target, mutable);

        mCodePastedListener = pListener;
    }

    @Override
    public boolean commitText(CharSequence text, int newCursorPosition)
    {
        String tfaCode = text.toString();
        // Just a regex to avoid dispatching incorrect 2FA code for me
        if (isValidTFACode(tfaCode))
        {
            mCodePastedListener.onTFACodePasted(tfaCode);
            // Returning false here avoid the wrapped InputConnection 
            // to dispatch it further has we already handled it.
            return false;
        }
        // On my side, I return false here too to only handle pasting the 2FA code my way 
        // but it could be useful to keep it in your case
        return super.commitText(text, newCursorPosition);
    }
}

最后,请记住,我们应该使用Receive rich content Unified API,并以下面的代码结尾:

ViewCompat.setOnReceiveContentListener(myEditText, new String[]{"text/*"}
                                       (view, payload) -> {
    ClipData clip = payload.getClip();
    if (clip.getItemCount() > 0)
    {
        String text = clip.getItemAt(0).coerceToText(getContext()).toString();
        if (isValidTFACode(text))
        {
            onTFACodePasted(text);
            return null;
        }
    }
    // We should return only unused ClipData.Items, not the whole payload...
    return payload;
});

但我不明白为什么键盘粘贴操作的处理方式不一样...
希望对大家有所帮助:)

相关问题