I m under delphi and i use the android framework to create an edit. When i set the theme to Theme.DeviceDefault.Light.NoActionBar then i can select some text in my EditText and i have a popup with "select all/cut/copy/paste/etc" like you can see on the picture below.
However, when i select Theme.Material.Light.NoActionBar or Theme.Holo.Light.NoActionBar then i can't select any text in my EditText (i have no right or left text selection handles) and off course i don't have any copy/paste popup
Is their any way to have this copy/paste popup on Theme_Material_Light_NoActionBar ?
Theme.DeviceDefault.Light.NoActionBar
Theme_Material_Light_NoActionBar
Theme.Holo.Light.NoActionBar
NOTE 1:
When i move the screen to the horizontal then the edittext take all the available space, and then i can see my right and left text selection handles like on the picture below, but i think it's because theme swap to Theme.DeviceDefault.Light.NoActionBar when i move the screen to the horizontal but i m not sure :
NOTE 2:
On my editText, when i do setCustomSelectionActionModeCallback(new Callback() {}) then the Callback is never called :( this is not normal i think ? What in the editText can forbid the callback ?
NOTE 2:
I can select text in all theme (but i can't copy it off course), but except in Theme.DeviceDefault.Light.NoActionBar i can't see the right and left text selection handle.
NOTE 3:
Theme.DeviceDefault.Light.NoActionBar show the right and left text selection handle only on some phones like the samsung galaxy. On some other it's didn't work.
NOTE 4:
i found partially the source of the problem! it's because i create my view via the WindowManager.addView(view, layout_params) and in this way startactionmodeforChild return null and this forbid the actionbar and the text selection handles to be show. Now if i do something like this in my edittext :
@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
Activity host = (Activity) this.getContext();
return host.getWindow().getDecorView().startActionMode(callback);
}
then i can see the right and left text action handles (but not on marshmallow, it's work only on lollipop this i don't know why). My problem now is that the actionbar is showed, but it's showed empty :( nothing is draw inside (but i can see that the cut/copy/past control are inside in the dump view hierarchie). So now i m not looking for a way to replace this actionbar by a popup menu instead (like on the picture Theme.DeviceDefault.Light.NoActionBar). Any idea ?
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).
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) {}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With