3

I were looking for solution on this question for long time, so I decided to ask it here.

Im writing Notepad App, after clicking on "new note" option, new Activity appears which looks like this:

NoteActivity screen with menu toolbar ON

Because of my app concept that allows user to edit text via format text menu (visible on bottom of screen) i want to allow user to select text, without showing keyboard on bottom and copy/cut/paste menu. Keyboard is accesed by toggle button (which works pretty well on 2 lines of code)

I've disabled keyboard popup when focus is set on EditText via following code:

public static void disableSoftInputFromAppearing(EditText editText) {
    if (Build.VERSION.SDK_INT >= 11) {
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);
    } else {
        editText.setRawInputType(InputType.TYPE_NULL);
        editText.setFocusable(true);
    }
}

Method called by keyboard button on app toolbar:

public void toggleKeyboard(MenuItem item) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
}

I'd like to select text (its achieved by double tapping on text or long pressing it), but the main problem is with copy/cut/paste toolbar, because it covers my app toolbar:

NoteActivity with copy/cut/paste toolbar covering app toolbar

That's why i'd like to get rid of this toolbar, but still get possibility of selecting specific text range.

P.S. Phone model: HTC One M7

Any help would be appreciated

Best regards, Tom

Tomek
  • 83
  • 1
  • 7

1 Answers1

1

For API level 11 or above then you can stop copy,paste,cut and custom context menus from appearing by.

edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {                  
        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }
    });

Returning false from onCreateActionMode(ActionMode, Menu) will prevent the action mode from being started(Select All, Cut, Copy and Paste actions). Originally answered HERE

Solution: Override isSuggestionsEnabled and canPaste in EditText.

For the quick solution, copy the class below - this class overrides the EditText class, and blocks all events accordingly.

For the gritty details, keep reading.

The solution lies in preventing PASTE/REPLACE menu from appearing in the show() method of the (non-documented) android.widget.Editor class. Before the menu appears, a check is done to if (!canPaste && !canSuggest) return;. The two methods that are used as the basis to set these variables are both in the EditText class:

isSuggestionsEnabled() is public, and may thus be overridden. canPaste() is not, and thus must be hidden by introducing a function of the same name in the derived class. So incorporating these updates into a class that also has the setCustomSelectionActionModeCallback, and the disabled long-click, here is the full class to prevent all editing (but still display the text selection handler) for controlling the cursor:

package com.cjbs.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;


/**
 *  This is a thin veneer over EditText, with copy/paste/spell-check removed.
 */
public class NoMenuEditText extends EditText

{
    private final Context context;

    /** This is a replacement method for the base TextView class' method of the same name. This 
     * method is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
     * appears when triggered from the text insertion handle. Returning false forces this window
     * to never appear.
     * @return false
     */
    boolean canPaste()
    {
       return false;
    }

    /** This is a replacement method for the base TextView class' method of the same name. This method
     * is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
     * appears when triggered from the text insertion handle. Returning false forces this window
     * to never appear.
     * @return false
     */
    @Override
    public boolean isSuggestionsEnabled()
    {
        return false;
    }

    public NoMenuEditText(Context context)
    {
        super(context);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    private void init()
    {
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        this.setLongClickable(false);
    }


    /**
     * Prevents the action bar (top horizontal bar with cut, copy, paste, etc.) from appearing
     * by intercepting the callback that would cause it to be created, and returning false.
     */
    private class ActionModeCallbackInterceptor implements ActionMode.Callback
    {
        private final String TAG = NoMenuEditText.class.getSimpleName();

        public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
        public void onDestroyActionMode(ActionMode mode) {}
    }
} 

Originally answered HERE2

Community
  • 1
  • 1
Stanojkovic
  • 1,612
  • 1
  • 17
  • 24
  • 1
    I've tried this solution before. It prevents from appearing custom context menu, but it also disables selecting text button. I've got a cursor, but I can't "separate this cursor" to select starting and ending node of selecting text. – Tomek Jan 29 '16 at 21:08
  • Yout next solution works same as first one. I've made some research and i've noticed, that its actually possible to select text while phone is in horizontal orientation mode. When i open keyboard while on horizontal mode, editText is the only thing i can see (except keyboard). Cursor changes color from app default to system default, thats really weird. I guess that i need to find another solution, maybe i wil just make space for copy/paste toolbar. Anyway, thanks for help, i really appreciate that :) – Tomek Jan 29 '16 at 22:21