On text selection, I do not want the user to see the Call option when they try to select a number from the TextView.
Is there a way to disable the call intent itself for the app?
I tried below, but I could not find the call option in the Menu to remove it.
fun TextView.disableCall() {
setCustomSelectionActionModeCallback(
object : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = false
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.apply {
//Could not find the call option menu to remove
removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
}
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
override fun onDestroyActionMode(mode: ActionMode?) {
// no-op
}
}
)
}
Related
I want hide option Paste when click double or Long Click Edittext
enter image description here
I tried:
edtSetName.customSelectionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(p0: ActionMode?, p1: Menu?): Boolean {
return true
}
override fun onPrepareActionMode(p0: ActionMode?, menu: Menu?): Boolean {
return false
}
override fun onActionItemClicked(p0: ActionMode?, p1: MenuItem?): Boolean {
return false
}
override fun onDestroyActionMode(p0: ActionMode?) {}
}
But that hide all option
I don't find a way to hide the menu popup, But you can disable it from pasting if the user taps on the menu
Create a custom EditText and override the onTextContextMenuItem method and return false for android.R.id.paste and android.R.id.pasteAsPlainText menu id's
#Override
public boolean onTextContextMenuItem(int id) {
switch (id){
case android.R.id.paste:
case android.R.id.pasteAsPlainText:
return false;
}
return super.onTextContextMenuItem(id);
}
I need to hide the copy,cut,select all and paste option when I double tap or long click the edit text view in Android application. I have checked several ways and the below is one of them that I checked. I also checked with android:longClickable="false" and android:textIsSelectable="false" in xml file. It needs to work in all the OS versions.Please check the attached screenshot.
Check the options that is displaying when long press the edit text view Check the different options displaying when double tap the edit text view
val callback: ActionMode.Callback = object : Callback, ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.apply {
removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
removeItem(android.R.id.paste)
removeItem(android.R.id.shareText) // Share
removeItem(android.R.id.textAssist)
}
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.removeItem(android.R.id.paste)
return true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return false
}
override fun onDestroyActionMode(mode: ActionMode?) {}
}
editText.setCustomInsertionActionModeCallback(callback)
editText.setCustomSelectionActionModeCallback(callback)
I hope you are well.
My question is why this callback class has two of the same functions?
the only difference that I see is that some functions deal with nullable and the others don't, but in the end, we can achieve what want with both ways (with nullable or without nullable)
if anyone has a good explanation for this and thanks in advance
private val actionModeCallback = object : Callback, android.view.ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
return false
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
return false // Return false if nothing is done
}
// Called when the user selects a contextual menu item
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
return false
}
// Called when the user exits the action mode
override fun onDestroyActionMode(mode: ActionMode) {
actionMode = null
}
override fun onCreateActionMode(p0: android.view.ActionMode?, p1: Menu?): Boolean {
// Called when the action mode is created; startActionMode() was called
// Inflate a menu resource providing context menu items
val inflater: MenuInflater = p0!!.menuInflater
inflater.inflate(R.menu.memory_fragment_context_menu, p1)
return true
}
override fun onPrepareActionMode(p0: android.view.ActionMode?, p1: Menu?): Boolean {
return false
}
override fun onActionItemClicked(p0: android.view.ActionMode?, p1: MenuItem?): Boolean {
return when (p1?.itemId) {
R.id.someId -> {
Toast.makeText(context,"go to hell", Toast.LENGTH_LONG).show()
selectionTracker?.clearSelection()
p0?.finish() // Action picked, so close the CAB
true
}
else -> false
}
}
override fun onDestroyActionMode(p0: android.view.ActionMode?) {
}
}
I want to use this callback as a method parameter in my class.
In order to avoid duplication at the moment I'm just declaring it in a local variable but I'm not sure this is a best practice.
What's the best way to achieve this?
private val callback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
mode?.menuInflater?.inflate(R.menu.items_contextual_action_bar, menu)
isInActionMode = true
return true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return when (item?.itemId) {
R.id.action_delete -> {
DeleteItemsDialogFragment().show(childFragmentManager, DeleteItemsDialogFragment.TAG.toString())
true
}
else -> false
}
}
override fun onDestroyActionMode(mode: ActionMode?) {
isInActionMode = false
tracker?.clearSelection()
actionMode = null
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean = false
}
I have a list activity in which the user can do open action modes A and B. The user can also open action mode A then B on top of it.
The problem is that when action mode A is shown and action mode B is shown on top of it, A gets closed automatically when B is shown. The user can't navigate back from B to A.
I thought I could take note of action mode A visibility when action mode B is opened then restore it when action mode B is closed, but that doesn't work. It seems that it's not possible to immediately show another action mode after closing one. However this issue only happens if the action mode A is closed with the back arrow. When closed by code (ActionMode.finish()), action mode B can be shown, but the closing animation doesn't make it look like user is navigating back from B to A. So this solution is out of question.
So is there a way to open an action mode on top of another, or at least replace the menu layout of an action mode programatically then change it back?
Action mode A is actually the search action mode, from which the user can select results which opens action mode B if that can help to understand.
I think I reached desired behavior through postDelayed() from onDestroyActionMode of action mode B.
This is not very elegant solution, but it works.
My code snippet:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listView.onItemClickListener = AdapterView.OnItemClickListener { adapterView, view, p2, p3 ->
startActionModeA()
true
}
}
var actionModeA: ActionMode? = null
val actionModeCallbackA = object : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode?, p1: MenuItem?): Boolean {
Log.wtf("ACTION MODE", "onActionItemClicked")
actionModeB = startActionMode(actionModeCallbackB)
return true
}
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
Log.wtf("ACTION MODE", "onCreateActionMode")
val inflater = mode?.getMenuInflater()
inflater?.inflate(R.menu.context_menu, menu)
return true
}
override fun onPrepareActionMode(p0: ActionMode?, p1: Menu?): Boolean {
Log.wtf("ACTION MODE", "onPrepareActionMode")
return false
}
override fun onDestroyActionMode(p0: ActionMode?) {
Log.wtf("ACTION MODE", "onDestroyActionMode")
actionModeA = null
}
}
var actionModeB: ActionMode? = null
val actionModeCallbackB = object : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode?, p1: MenuItem?): Boolean {
Log.wtf("ACTION MODE 2", "onActionItemClicked")
return true
}
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
Log.wtf("ACTION MODE 2", "onCreateActionMode")
val inflater = mode?.getMenuInflater()
inflater?.inflate(R.menu.context_menu2, menu)
return true
}
override fun onPrepareActionMode(p0: ActionMode?, p1: Menu?): Boolean {
Log.wtf("ACTION MODE 2", "onPrepareActionMode")
return false
}
override fun onDestroyActionMode(mode: ActionMode?) {
Log.wtf("ACTION MODE 2", "onDestroyActionMode")
actionModeB = null
listView.postDelayed({
startActionModeA()
}, 100)
}
}
private fun startActionModeA() {
actionModeA = startActionMode(actionModeCallbackA)
}