web-dev-qa-db-fra.com

Comment désactiver le copier / coller de / vers EditText

Dans mon application, il y a un écran d'enregistrement, où je ne veux pas que l'utilisateur puisse copier/coller du texte dans le champ EditText. J'ai défini un onLongClickListener sur chaque EditText afin que le menu contextuel affichant la méthode copier/coller/méthode d'entrée et les autres options n'apparaissent pas. Ainsi, l'utilisateur ne pourra pas copier/coller dans les champs d'édition.

 OnLongClickListener mOnLongClickListener = new OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            // prevent context menu from being popped up, so that user
            // cannot copy/paste from/into any EditText fields.
            return true;
        }
    };

Mais le problème se pose si l’utilisateur a activé un clavier tiers autre que le Android par défaut), qui peut comporter un bouton à copier/coller ou afficher le même menu contextuel. je désactive copier/coller dans ce scénario?

S'il vous plaît laissez-moi savoir s'il existe d'autres moyens de copier/coller aussi. (et éventuellement comment les désactiver)

Toute aide serait appréciée.

116
rDroid

Si vous utilisez une API de niveau 11 ou supérieur, vous pouvez empêcher les menus contextuels de copier, coller, couper et personnalisés de s'afficher.

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;
            }
        });

Le renvoi de false à partir de onCreateActionMode (ActionMode, Menu) empêchera le démarrage du mode d'action (actions Tout sélectionner, Couper, Copier et Coller).

108
Zain Ali

La meilleure méthode consiste à utiliser:

etUsername.setLongClickable(false);
117
Vicky Kapadia

Vous pouvez le faire en désactivant l'appui long du EditText

Pour l'implémenter, ajoutez simplement la ligne suivante dans le fichier xml -

Android:longClickable="false"
35
Ameya Pandilwar

Je peux désactiver la fonctionnalité copier-coller avec les éléments suivants:

textField.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

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

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

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

    public void onDestroyActionMode(ActionMode actionMode) {
    }
});

textField.setLongClickable(false);
textField.setTextIsSelectable(false);

J'espère que ça marche pour toi ;-)

34
Joseph Johnson

voici un meilleur moyen de désactiver le copier/coller coller du travail editText dans toutes les versions

if (Android.os.Build.VERSION.SDK_INT < 11) {
        editText.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

            @Override
            public void onCreateContextMenu(ContextMenu menu, View v,
                    ContextMenuInfo menuInfo) {
                // TODO Auto-generated method stub
                menu.clear();
            }
        });
    } else {
        editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                // TODO Auto-generated method stub
                return false;
            }

            public void onDestroyActionMode(ActionMode mode) {
                // TODO Auto-generated method stub

            }

            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // TODO Auto-generated method stub
                return false;
            }

            public boolean onActionItemClicked(ActionMode mode,
                    MenuItem item) {
                // TODO Auto-generated method stub
                return false;
            }
        });
    }
12
Hardik

En plus des setCustomSelectionActionModeCallback , et clic long désactivé solutions, il est nécessaire de empêcher les menus PASTE/REPLACE d'apparaître lorsque la poignée de sélection de texte est cliqué, selon l'image ci-dessous:

Text selection handle with paste menu

La solution consiste à empêcher le menu PASTE/REPLACE d’apparaître dans la méthode show() de la classe (non documentée) Android.widget.Editor. Avant que le menu apparaisse, une vérification est faite pour if (!canPaste && !canSuggest) return;. Les deux méthodes utilisées comme base pour définir ces variables sont toutes deux de la classe EditText:

Une réponse plus complète est disponible ici .

9
CJBS

En utilisant d'autres solutions, l'API 26 (Oreo) montrait toujours la poignée du curseur en appuyant simplement sur le texte saisi, puis le menu pouvait être affiché. Seule une combinaison de solutions peut résoudre mon problème.

public class CustomEditText extends EditText {

    public CustomEditText(Context context) {
        super(context);
        init();
    }

    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    /**
    * This method sets TextView#Editor#mInsertionControllerEnabled field to false
    * to return false from the Editor#hasInsertionController() method to PREVENT showing
    * of the insertionController from EditText
    * The Editor#hasInsertionController() method is called in  Editor#onTouchUpEvent(MotionEvent event) method.
    */
    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            Class editorClass = Class.forName("Android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        }
        catch (Exception ignored) {
            // ignore exception here
        }
    }

    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }

    private class BlockedActionModeCallback implements ActionMode.Callback {
        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) {
        }
    }
}
6
water

Solution Kotlin:

fun TextView.disableCopyPaste() {
    customSelectionActionModeCallback = object : ActionMode.Callback {
        override fun onCreateActionMode(mode: ActionMode?, menu: Menu): Boolean {
            return false
        }

        override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean {
            return false
        }

        override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
            return false
        }

        override fun onDestroyActionMode(mode: ActionMode?) {}
    }
    isLongClickable = false
    setTextIsSelectable(false)
}

Ensuite, vous pouvez simplement appeler cette méthode sur votre TextView:

override fun onCreate() {
    priceEditText.disableCopyPaste()
}
5
Alexandr

Si vous ne voulez pas désactiver le clic long car vous devez exécuter certaines fonctionnalités sur un clic long, renvoyer true est une meilleure option.

Votre clic long edittext sera comme ça.

edittext.setOnLongClickListener(new View.OnLongClickListener() {
      @Override
      public boolean onLongClick(View v) {
            //  Do Something or Don't
            return true;
      }
});

Selon documentation Si vous retournez "True", cela signifiera que les clics longs ont été gérés, il n'est donc pas nécessaire d'effectuer d'opérations par défaut.

J'ai testé cela aux niveaux 16, 22 et 25 de l'API. Cela fonctionne très bien pour moi. J'espère que cela aidera.

4
muak

https://github.com/neopixl/PixlUI fournit un EditText avec une méthode

myEditText.disableCopyAndPaste().

Et ça marche sur l'ancienne API

3
odemolliens

Voici un hack pour désactiver "coller" le popup. Vous devez remplacer la méthode EditText:

@Override
public int getSelectionStart() {
    for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
        if (element.getMethodName().equals("canPaste")) {
            return -1;
        }
    }
    return super.getSelectionStart();
}

De même peut être fait pour les autres actions.

2
Anton Tananaev

@Zain ALi, votre réponse fonctionne sur l'API 11. Je voulais simplement suggérer un moyen de faire de même sur l'API 10. Comme je devais maintenir l’API de mon projet sur cette version, je jouais constamment avec les fonctions disponibles dans la version 2.3.3 et j’avais la possibilité de le faire. J'ai partagé l'extrait ci-dessous. J'ai testé le code et cela fonctionnait pour moi. J'ai fait cet extrait en urgence. N'hésitez pas à améliorer le code si des modifications peuvent être apportées.

// A custom TouchListener is being implemented which will clear out the focus 
// and gain the focus for the EditText, in few milliseconds so the selection 
// will be cleared and hence the copy paste option wil not pop up.
// the respective EditText should be set with this listener 
// tmpEditText.setOnTouchListener(new MyTouchListener(tmpEditText, tmpImm));

public class MyTouchListener implements View.OnTouchListener {

    long click = 0;
    EditText mEtView;
    InputMethodManager imm;

    public MyTouchListener(EditText etView, InputMethodManager im) {
        mEtView = etView;
        imm = im;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            long curr = System.currentTimeMillis();
            if (click !=0 && ( curr - click) < 30) {

                mEtView.setSelected(false);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mEtView.setSelected(true);
                        mEtView.requestFocusFromTouch();
                        imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
                    }
                },25);

            return true;
            }
            else {
                if (click == 0)
                    click = curr;
                else
                    click = 0;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mEtView.requestFocusFromTouch();
                        mEtView.requestFocusFromTouch();
                        imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
                    }
                },25);
            return true;
            }

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            mEtView.setSelected(false);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mEtView.setSelected(true);
                    mEtView.requestFocusFromTouch();
                    mEtView.requestFocusFromTouch();
                    imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
                }
            },25);
            return true;
        }
        return false;
    }
1
Aravind

Essayez de suivre un css personnalisé pour empêcher le copier-coller dans Edittext

public class SegoeUiEditText extends AppCompatEditText {
private final Context context;


@Override
public boolean isSuggestionsEnabled() {
    return false;
}
public SegoeUiEditText(Context context) {
    super(context);
    this.context = context;
    init();
}

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

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


private void setFonts(Context context) {
    this.setTypeface(Typeface.createFromAsset(context.getAssets(), "Fonts/Helvetica-Normal.ttf"));
}

private void init() {

        setTextIsSelectable(false);
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        this.setLongClickable(false);

}
@Override
public int getSelectionStart() {

    for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
        if (element.getMethodName().equals("canPaste")) {
            return -1;
        }
    }
    return super.getSelectionStart();
}
/**
 * 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, Android.view.ActionMode.Callback {
    private final String TAG = SegoeUiEditText.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) {}

    @Override
    public boolean onCreateActionMode(Android.view.ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onPrepareActionMode(Android.view.ActionMode mode, Menu menu) {
        menu.clear();
        return false;
    }

    @Override
    public boolean onActionItemClicked(Android.view.ActionMode mode, MenuItem item) {
        return false;
    }

    @Override
    public void onDestroyActionMode(Android.view.ActionMode mode) {

    }
}

}

1
Sagar Jethva

J'ai testé cette solution et cela fonctionne

    mSubdomainEditText.setLongClickable(false);
    mSubdomainEditText.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;
      }
    });
1
Aakash Anuj

Pour smartphone avec presse-papiers, il est possible d'empêcher comme ça.

editText.setFilters(new InputFilter[]{new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (source.length() > 1) {
                return "";
            }  return null;
        }
    }});
1
José Torres

la solution est très simple

public class MainActivity extends AppCompatActivity {

EditText et_0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et_0 = findViewById(R.id.et_0);

    et_0.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            //to keep the text selection capability available ( selection cursor)
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            //to prevent the menu from appearing
            menu.clear();
            return false;
        }

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

        @Override
        public void onDestroyActionMode(ActionMode mode) {

        }
    });
   }
}

--------> preview <---------

1
Muhammad Ali

Lisez le Presse-papiers, vérifiez l’entrée et le moment où elle est "saisie". Si le Presse-papiers contient le même texte et qu'il est trop rapide, supprimez l'entrée collée.

1
kadir

Essayez d'utiliser.

myEditext.setCursorVisible(false);

       myEditext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // TODO Auto-generated method stub
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
            // TODO Auto-generated method stub

        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // TODO Auto-generated method stub
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode,
                MenuItem item) {
            // TODO Auto-generated method stub
            return false;
        }
    });
0
Thambidurai

Semblable à GnrlKnowledge, vous pouvez effacer le Presse-papiers

http://developer.Android.com/reference/Android/text/ClipboardManager.html

Si vous le souhaitez, conservez le texte dans le Presse-papiers et, sur onDestroy, vous pouvez le redéfinir.

0
Kevin D.

La solution qui a fonctionné pour moi a été de créer Edittext personnalisé et de remplacer la méthode suivante:

public class MyEditText extends EditText {

private int mPreviousCursorPosition;

@Override
protected void onSelectionChanged(int selStart, int selEnd) {
    CharSequence text = getText();
    if (text != null) {
        if (selStart != selEnd) {
            setSelection(mPreviousCursorPosition, mPreviousCursorPosition);
            return;
        }
    }
    mPreviousCursorPosition = selStart;
    super.onSelectionChanged(selStart, selEnd);
}

}

0
Palejandro

J'ai constaté que lorsque vous créez un filtre de saisie pour éviter la saisie de caractères indésirables, le collage de tels caractères dans le texte de modification n'a aucun effet. Donc, cela résout mon problème aussi.

0
rDroid

Vous pouvez essayer Android: focusableInTouchMode = "false".

0
stdout