Highlight text in WebView with Long Tap

cbanks

Active Member
Licensed User
Longtime User
I've made an app that amounts to a book reader. What code would be necessary to allow someone to long tap on a paragraph and it would highlight that paragraph? Any time they go to that paragraph it would be highlighted. If they long tap it again then the highlight will remove. Thanks.
 

cbanks

Active Member
Licensed User
Longtime User
warwound: do you know how I would allow the user to be able to drag over whatever words they want and then it would highlight those words when they're done?
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Hi again.

The only solution i can think of is:

A tap on a word highlights the paragraph that contains that word.

A tap on a word in an already highlighted paragraph could be detected and the word highlighted differently to the already highlighted paragraph.

But that would break the existing code where a tap on a highlighted paragraph causes the paragraph to be not highlighted.

Maybe a long tap event listener could be used so the code works as it does now but a long tap on a word marks it as 'selected'.

Unfortunately javascript has no long tap or long click event listeners, and creating your own listener using timers to detect if a tap or click is a long tap or long click gets pretty complicated and generally does work very well...

A tap or click would not be actioned until a timer has decided that the tap or click is not a long tap or long click.
You can set the timer interval that defines how long should be considered a long tap or click.
Set that interval to say 250ms and your long tap or long click action will work.
But a normal tap or click will not be actioned until 250ms after the tap or click.
Decrease the interval and a tap can be confused with a long tap.
Increase the interval and the delay before a tap (not long tap) is actioned increases.

Maybe the best solution would be:

A tap on an unhighlighted word highlights the paragraph containing the word.

A tap on a word in a highlighted paragraph highlights that word differently from the paragraph.

A double tap on a highlighted paragraph unhighlights the entire paragraph and all words in the paragraph.

Touch and drag to select may be possible but i've no idea how it'd be implemented in a WebView and i suspect it'd be un-useable on many devices with poor quality screens.

The WebView just isn't very touch friendly or versatile.

Ultimately i think your best bet would be to create a custom native Android View (as a library) that displays basic HTML and can use the native Android touch event system.
(The native Android touch events not being accessible from a WebView javascript).
You still have problem with devices that have poor quality screens but i think that's the best you can hope for.

Martin.
 
Last edited:
Upvote 0

cbanks

Active Member
Licensed User
Longtime User
Thanks for the explanation. So, what view would be better to use than a webview to display my html pages? I don't know anything about creating custom view as a library.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
I was originally thinking something along the lines of a ScrollView containing a TextView (Label).

There's a native Android method that can take an HTML String and parse it to a format that can be added to a TextView and the TextView will render the HTML tags: Html | Android Developers.

BUT after a little research it seems as though very few HTML tags are supported by this method: The CommonsBlog — HTML Tags Supported By TextView.
That blog is a little dated but shows that not many HTML tags can be displayed in a TextView.

Also now i've thought about it a bit, creating such a custom View would mean an awful lot of work...
The custom view wouldn't support a tag such as <a href="1.html#6b"><sup>b</sup>quake</a> - the custom View wouldn't automatically scroll to the desired anchor.

The custom View would in fact be re-inventing the wheel - creating a WebView that does exactly as you want because the native WebView doesn't support the javascript events to detect tap and drag to select a word.

So back to the standard WebView and how to update your javascript as best as possible.

Maybe the best solution would be:

A tap on an unhighlighted word highlights the paragraph containing the word.

A tap on a word in a highlighted paragraph highlights that word differently from the paragraph.

A double tap on a highlighted paragraph unhighlights the entire paragraph and all words in the paragraph.

That's still the best and simplest to implement solution i can think of.

Martin.
 
Upvote 0

cbanks

Active Member
Licensed User
Longtime User
I'm willing to change from a webview to something else if I need to. The way I want it to work is have the user long-top and then it gives them the beginning and ending thingies that they can drag where they want. When they tap somewhere else when they're done, it will highlight between the beginning and ending thingies.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Ah yes - the built in Android text selection capability - didn't think of that before.

https://www.google.co.uk/search?q=android+webview+select+text&ie=UTF-8&oe=UTF-8

Not impossible and there's a few code examples out there, the code in this thread looks easiest to start with: User selectable text in WebView - Android Developers | Google Groups.

So i'd need to create a new library, extend the native Android WebView with the new copy to clipboard functionality and then wrap that extended WebView in a wrapper class so it can be used in B4A - you'd then replace your existing uses of WebView with the new WebView.
Easy if you're creating WebViews in code but if you're using the Designer to add a WebView you'd have to change to creating the new extended WebView by code.

If it works then the new library would generate a 'clipboard_ready' or 'selection_ready' event, passing the selected text to a Sub for your Activity to process.

I'll make a start on the new library a bit later and post back with my results.

Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
I have a little progress to report, i have created the SelectableWebView!

B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim SelectableWebView1 As SelectableWebView
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.AddMenuItem("EnableSelection", "MenuItem")

   SelectableWebView1.Initialize("SelectableWebView1")
   Activity.AddView(SelectableWebView1, 0, 0, 100%x, 100%y)
   
   SelectableWebView1.LoadUrl("http://www.b4x.com/forum/basic4android-updates-questions/14437-highlight-text-webview-long-tap-3.html#post99556")
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub MenuItem_Click
   SelectableWebView1.EnableSelectionMode
End Sub

Sub SelectableWebView1_SelectionReady(SelectedText As String)
   Msgbox(SelectedText, "Selected text:")
End Sub

The SelectableWebView has just one method to look at:

EnableSelectionMode

Puts the WebView into text selection mode.

Run the project and use the Menu key to enable text selection mode - it all works fine i think.

Android automatically displays a Toast message Text copied to clipboard - a search on Google shows that it's probably not possible to suppress that message.

You could get strange results if the user currently has text pasted into the Android clipboard or if they use the clipboard in another application while also using your application - i might be able to find a workaround for that.

And if you're happy with this selection method i'll need to add all the standard WebView methods to it - EnableSelectionMode and LoadUrl are it's only two methods at the moment.

An idea - when text selection mode is enabled, disable the web page javascript that hightlights text so as to not cause a conflict between highlighting and selection.

Demo code and alpha version of the library are attached, have a play and let me know if you want me to develop the new library further.

Martin.
 
Last edited:
Upvote 0

warwound

Expert
Licensed User
Longtime User
Here's an update for you.

I've taken the B4A WebViewWrapper and added the single new EnableSelectionMode to that.

It works the same as previously posted but you can now access all the standard WebView methods as well as my new EnableSelectionMode method.

You should now be able to try and integrate it into your existing code and see how well it works.

As mentioned before - there could be conflicts between touch events if selection and highlighting code both work at the same time but it should be easy to disable the web page javascript highlighting function when selection mode is enabled and re-enable highlighting after a selection has been made.

Version 1.01 of SelectableWebView attached and the original version in my last post removed.

Martin.
 

Attachments

  • SelectableWebViewDemo.zip
    12.3 KB · Views: 584
Upvote 0

cbanks

Active Member
Licensed User
Longtime User
I took a look at the demo and saw how it has the msgbox with the selected text. How do I then go about highlighting that text? Sorry, newbie = lost.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
I think you'd have to create another javascript function in the web page and call that function from your Activity - in the SelectionReady Sub.

Pass the SelectedText to the new javascript function and the function would find the text and highlight it.

But that function would have to find and highlight all occurences of the selected text i think...

If the user highlighted common text such as 'the' then the javascript function wouldn't know which occurence of 'the' had been highlighted, so highlighting all occurences would be the only option.

Is that any use or must you be able to highlight the exact single occurence of the selected text?

Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Hi again.

I'm been researching for a way to do this but nothing seems to quite be able to do the job...

Javascript in a WebView can detect both Mouse and Touch events.

A Mouse event can return the HTML element that was clicked/double-clicked for example.

A Touch event can return the coordinates of the point that was tapped.

Neither of those will enable javascript to know what character the user has tapped or clicked in order to start highlighting or end highlighting.

The previously post Android code that enables text selection can do just that - enable text selection and paste the selected text to the clipboard.
It's of no use if you want to select part of a web page and apply highlighting.
If the user highlighted text that occured just ONCE in the web page then it could probably be used.
But if the clipboard contains text that occurs more than once in the web page then this method is again of no use.

For something which should be 'do-able' this all sounds rather impossible...

Martin.
 
Upvote 0

andrewj

Active Member
Licensed User
Longtime User
Hi Martin,
I'm already using your FlingableWebView, which works well for what I want. However it would be great if this also had the selection features. Is there any chance of bringing these together?

Also I see in #33 that you think that "Mouse Events" can return information about the HTML element under a click. This would be very useful to me as I want to enable image downloading, and this would allow me to get at the <img> tag information. Is this something I can do in FlingableWebView, or is it something you'd have to build in?

Thanks
Andrew
 
Upvote 0

cbanks

Active Member
Licensed User
Longtime User
I think you'd have to create another javascript function in the web page and call that function from your Activity - in the SelectionReady Sub.

Pass the SelectedText to the new javascript function and the function would find the text and highlight it.

But that function would have to find and highlight all occurences of the selected text i think...

If the user highlighted common text such as 'the' then the javascript function wouldn't know which occurence of 'the' had been highlighted, so highlighting all occurences would be the only option.

Is that any use or must you be able to highlight the exact single occurence of the selected text?

Martin.

Martin, I'm not concerned now about highlighting more than one occurrence of a word on a page. I would like to know more about how to pass the selectedtext and have it highlighted on the page. I'd also like to be able to select the same text and un-highlight it as well.

Maybe this page can even give you some ideas on how to only highlight the specifc selected text: http://forums.asp.net/t/1903574.aspx?highlight and remove highlight of selected text using javascript

So, the way I'd like it to work is the user long-taps in the webview, drags the beginning and end markers to select the text they want to highlight, the user taps away or taps a button in the app to highlight and the selected text is highlighted. I'll then save that page so that when the user loads it again, that selected text is still highlighted.
 
Last edited:
Upvote 0

hzchrisfang

Member
Licensed User
Longtime User
Hi Martin. How can I make a selection with code? For example, search a word in the content of the web, then select the word and highlight. It possible?
 
Upvote 0
Top