Overriding the default Contextual Action Bar for text selection(in WebView) in Android
Asked Answered
D

2

27

I want to override the existing default Contextual Action Bar(CAB) for text selection. I mean, I want to display my own CAB, with my own buttons, when some text is selected on the webview. I tried implementing a CAB using Android Documentation. OnLongClickListener doesn't capture the text selection event in the web view. What is the event that captures text selection? Is it possible to hide the default CAB and display my CAB on Text selection?

childWebView.setOnLongClickListener(new OnLongClickListener() {
        @Override
     // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (mActionMode != null) {
                return false;
            }

            // Start the CAB using the ActionMode.Callback defined above
            mActionMode = startActionMode(mActionModeCallback);
            view.setSelected(true);
            return true;
        }
    });
Delly answered 12/3, 2013 at 19:10 Comment(7)
did you find a solution for that karka ?Billye
any solution till now?Bradytelic
I am too looking for the solution.Jeromejeromy
@matiash, please be careful when creating new tags. We already had a tag for the Android Contextual Action Bar.Alderete
@Alderete I'm sorry, you're absolutely right. I found it while I was retagging a few questions. That's why I stopped. :/ But shouldn't all android tags have the android- prefix?Damnatory
@matiash, if at all possible, yes, but acronyms ("cab") are worse. Remember, a lot of people don't read tag wikis.Alderete
@Charles. OK. Learned the lesson. Won't happen again :)Damnatory
S
9

I have been able to resolve this. I was also facing this issue and could not find any solution on the web.

So, if you set up a LongClick listener, the Webview would stop showing selection at all. After delving deep into the Webview code, I found that it was calling WebView's method startRunMode and passing an instance of SelectActionCallbackMode class.

I simply extended the Webview class and overrided the startRunMode method like this:

public ActionMode startActionMode(ActionMode.Callback callback) 
{
    actionModeCallback = new CustomizedSelectActionModeCallback();
    return super.startActionMode(actionModeCallback);
}

This forced the Webview to display my Callback instead of displaying Webview's default one. This ensured that selection worked as smoothly as before and my CAB was displayed each time selection was made. Only caveat was that I had to write code to dismiss the CAB myself.

Tested on 4.1, 4.2 and 4.3 devices.

Hope this helps.

Spadework answered 7/2, 2014 at 11:33 Comment(7)
But you cannot get the selected text from the webview. Also, in my implementation I sometimes get an internal error in the Kitkat webview, using this approach.Arabelle
@Arabelle You can get the selected text via JavaScript (window.getSelection().toString()). I haven't tried it on KitKat yet, will try and look at the issue.Spadework
Have you had any luck with this on 4.4? I did the same thing, but if the selection is changed at all, the app crashes upon picking an action.Introspection
It works perfectly for me on 4.4. Moreover on 4.4, there is no need to dismiss the CAB manually. It is automatically hidden by Android.Spadework
hey thanks pulkit. With your effort I was able to hide the default CAB but the problem is the text selection on webview(on long click) goes away too. The comment that you made above regarding the use of javascript will be helpful only if the text is selected. In my case the text is not getting selected onLongClick at all. ThanksAcquire
I am a little confused. Are you not able to select text or the selection goes away? The selection should not go away. We have not done anything special to retain selection. Just ensure that you are not blocking the call to the super class. In case the text is not getting selected, please ensure you don't have the longclick listener added as that'd block the selection.Spadework
@PulkitGupta : how to open custom dialog on text selection instead of default copy dialog ?Prostrate
N
1

The official documentation Selection | Android Developers notes that:

Selecting CAB actions

You can decide which actions and elements appear in the CAB. Use the guidelines in the Action Bar pattern to decide which items to surface at the top level and which to move to the action overflow.

Dynamically adjust CAB actions In most cases you need to adjust the actions in the CAB dynamically as the user adds more items to the selection. Actions that apply to a single selected data item don't necessarily apply to multiple selected data items of the same kind.

Unfortunately, the link included in the quote links to a section which also only holds general information without actually going into details. To make things worse, it links back to the Selection | Android Developers page.

Looking a bit further, I found this tutorial from Lars Vogel. I quote (formatting mine):

A contextual action mode activates a temporary ActionBar that overlays the application ActionBar for the duration of a particular sub-task.

The contextual action mode is typically activated by selecting an item or by long clicking on it.

To implemented this, call the startActionMode() method on a View or on your activity. This method gets an ActionMode.Callback object which is responsible for the lifecycle of the contextual ActionBar.

You could also assign a context menu to a View via the registerForContextMenu(view) method. A context menu is also activated if the user "long presses" the view. The onCreateContextMenu() method is called every time a context menu is activated as the context menu is discarded after its usage. You should prefer the contextual action mode over the usage of context menus.

The most prominent reference mentions that we can create our own menu using registerForContextMenu(view). Rather than duplicating an answer, I found this answer by J. Pablo Fernández which contains a code example on how to apply your own CAB. Registering a new context menu should override any default menu but I am not sure. As I am unable to test this at the moment, I would be glad to hear whether this solved your problem.

Nesto answered 23/8, 2013 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.