简体   繁体   English

不使用富文本格式粘贴到 EditText 中

[英]Paste without rich text formatting into EditText

If I copy/paste text from Chrome for Android into my EditText view it gets messed up, apparently due to rich text formatting.如果我将 Chrome for Android 中的文本复制/粘贴到我的 EditText 视图中,它会变得一团糟,显然是由于富文本格式。

Is there a way to tell the EditText view to ignore rich text formatting?有没有办法告诉 Edi​​tText 视图忽略富文本格式? Or can I catch the paste event and remove it before it gets set?或者我可以捕获粘贴事件并在设置之前将其删除吗? How would I do that?我该怎么做?

UPDATE: So I realized that the editText.getText() gives me a SpannableString that contains some formatting.更新:所以我意识到editText.getText()给了我一个包含一些格式的SpannableString I can get rid of that by calling .clearSpans();我可以通过调用.clearSpans();来摆脱它.clearSpans(); on it.在上面。 BUT I cannot do anything like that in editText.addTextChangedListener(new TextWatcher() { … } because it gets terribly slow and the UI only updates when I leave the editText view.但是我不能在editText.addTextChangedListener(new TextWatcher() { … }做任何类似的事情,因为它变得非常慢,而且 UI 只有在我离开 editText 视图时才会更新。

A perfect and easy way: Override the EditText 's onTextContextMenuItem and intercept the android.R.id.paste to be android.R.id.pasteAsPlainText一个完美而简单的方法:覆盖EditTextonTextContextMenuItem并将android.R.id.paste拦截为android.R.id.pasteAsPlainText

@Override
public boolean onTextContextMenuItem(int id) {
    if (id == android.R.id.paste) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            id = android.R.id.pasteAsPlainText;
        } else {
            onInterceptClipDataToPlainText();
        }
    }
    return super.onTextContextMenuItem(id);
}


private void onInterceptClipDataToPlainText() {
    ClipboardManager clipboard = (ClipboardManager) getContext()
        .getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = clipboard.getPrimaryClip();
    if (clip != null) {
        for (int i = 0; i < clip.getItemCount(); i++) {
            final CharSequence paste;
            // Get an item as text and remove all spans by toString().
            final CharSequence text = clip.getItemAt(i).coerceToText(getContext());
            paste = (text instanceof Spanned) ? text.toString() : text;
            if (paste != null) {
                ClipBoards.copyToClipBoard(getContext(), paste);
            }
        }
    }
}

And the copyToClipBoard:和 copyToClipBoard:

public class ClipBoards {

    public static void copyToClipBoard(@NonNull Context context, @NonNull CharSequence text) {
        ClipData clipData = ClipData.newPlainText("rebase_copy", text);
        ClipboardManager manager = (ClipboardManager) context
            .getSystemService(Context.CLIPBOARD_SERVICE);
        manager.setPrimaryClip(clipData);
    }
}

The problem with clearSpans() was that it removed too much and the editText behaves weird thereafter. clearSpans()的问题在于它删除了太多,之后 editText 的行为很奇怪。 By following the approach in this answer I only remove the MetricAffectingSpan and it works fine then.通过遵循此答案中的方法,我只删除了MetricAffectingSpan ,然后它就可以正常工作了。

For me the only problem was the size of the text.对我来说唯一的问题是文本的大小。 If you have other problems you'd have to adjust what you want to remove.如果您有其他问题,则必须调整要删除的内容。

public void afterTextChanged(Editable string)
{
    CharacterStyle[] toBeRemovedSpans = string.getSpans(0, string.length(),
                                                MetricAffectingSpan.class);
    for (int index = 0; index < toBeRemovedSpans.length; index++)
        string.removeSpan(toBeRemovedSpans[index]);
    }
}

Erik's answer above removes few formatting, but not all.上面埃里克的回答删除了很少的格式,但不是全部。 Hence I used:因此我使用了:

CharacterStyle[] toBeRemovedSpans = string.getSpans(0, string.length(), CharacterStyle.class);

to remove all formatting.删除所有格式。

This simple copy and paste should give you text without formatting:这个简单的复制和粘贴应该给你没有格式的文本:

public void paste(View v) {
    int sdk = android.os.Build.VERSION.SDK_INT;
    if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
        android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        editText.setText(clipboard.getText());
    } else {
        android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        android.content.ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);

        if (item.getText() != null) {
            editText.getText().insert(editText.getSelectionStart(), item.getText());
        }
    }
    editText.setSelection(0);
}

public void copy(View v) {
    if (editText.getText() != null) {
        String selectedText = editText.getText().toString();

        int start = editText.getSelectionStart();
        int end = editText.getSelectionEnd();

        if (end > start) {
            selectedText = selectedText.substring(start, end);

            int sdk = android.os.Build.VERSION.SDK_INT;
            if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
                android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                clipboard.setText(selectedText);
            } else {
                android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                android.content.ClipData clip = android.content.ClipData.newPlainText("WordKeeper", selectedText);
                clipboard.setPrimaryClip(clip);
            }
        } else
            Toast.makeText(this, "To copy, select some text first by pressing and and holding the text area.", Toast.LENGTH_SHORT).show();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM