Paste without rich text formatting into EditText

后端 未结 4 616
一个人的身影
一个人的身影 2020-12-16 12:09

If I copy/paste text from Chrome for Android into my EditText view it gets messed up, apparently due to rich text formatting.

Is there a way to tell the EditText vie

相关标签:
4条回答
  • 2020-12-16 12:40

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-16 12:45

    A perfect and easy way: Override the EditText's onTextContextMenuItem and intercept the android.R.id.paste to be 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:

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-16 12:46

    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.

    0 讨论(0)
  • 2020-12-16 12:47

    The problem with clearSpans() was that it removed too much and the editText behaves weird thereafter. By following the approach in this answer I only remove the MetricAffectingSpan and it works fine then.

    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]);
        }
    }
    
    0 讨论(0)
提交回复
热议问题