Sunday, September 30, 2018

How to show HTML text in Android while detecting clicks on specific phrases and scrolling position?

Leave a Comment

I'm getting a wall of plain HTML text from the server and need to render it in my application, but that's not all.

I also need to detect clicks on specific phrases within the text. The phrases are defined by two numbers: word count where the phrase starts and word count where it ends (e.g. from word 10 to word 15).

My intuition says that I could probably instrument the HTML with links or some JavaScript according to phrases spec and then listen for clicks on these links. However, I'm not sure how to achieve this kind of functionality in Android.

In addition, I also need to be able to programmatically observe and manipulate the scrolling position within the shown HTML text. For instance, I'll need to understand when a specific phrase is scrolled off the screen.

I guess I have three closely related questions:

  1. Which View should I use to achieve the above functionality (TextView, WebView, other)?
  2. How can I listen for clicks on specific parts of HTML?
  3. How can I observe and manipulate the scrolling position?

Thanks

5 Answers

Answers 1

  1. WebView is a quick way to do this.
  2. You can map a java/kotlin function to the javascript function on the webpage to track clicks.
  3. Again using simple jquery , you can achieve it.

Refer to : slymax web view

Answers 2

I think you can do this by using this method : 1.) You need to get all links from the html text you have. So to do this use this method :

 public static ArrayList<String> extractUrls(String text) {     ArrayList<String> containedUrls = new ArrayList<>();     String urlRegex = "((https?|ftp|gopher|telnet|file):((//)|(\\\\))+[\\w\\d:#@%/;$()~_?\\+-=\\\\\\.&]*)";     Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE);     Matcher urlMatcher = pattern.matcher(text);      while (urlMatcher.find()) {         containedUrls.add(text.substring(urlMatcher.start(0),                 urlMatcher.end(0)));     }     return containedUrls; } 

It will return an ArrayList of URLs, Now you need to convert the HTML data into human readable text : To do this use :

public void HtmlToString(final String data) {     Thread thread = new Thread(new Runnable() {         @Override         public void run() {             final String s = String.valueOf(Html.fromHtml(data));             runOnUiThread(new Runnable() {                 @Override                 public void run() {                     processData(s);                 }             });         }     });     thread.start(); } void processData(String s){ // Do whatever you want to do } 

We are doing this work on another thread. Now, You have text as well as links, do whatever you want with this. Now if you want to do more work on it you may do this by replacing all the links you get in array list with a special code that you can use as a placeholder like :

for(int i = 0; i < urlArray.size();i++){     yourData.replace(urlArray.get(i),"<<<YOURSPECIALCODE>>>");        } 

Now you can break your data using your Special code to get the breaks at the place of URLs. To do that :

ArrayList<String> dataArray = new ArrayList<>(yourData.split("<<<YOURSPECIALCODE>>>")); 

Now you can use these two arrays to show according to your requirements

As now You can assign different text views to different data and setOnClick Listeners to them very easily.

Hope it may help!

Thank you

Answers 3

In case you are planning to use TextView (I would prefer to if the content isn't supposed to be rendered as a full HTML, use WebView otherwise) and use Clickable span within the text content to make specific areas clickable. You can handle the click on individual span areas and perform the required actions in the click handler. You need to write multiple CustomClickableSpan classed based on the number of different clickable areas you wish to handle.

Answers 4

I guess for you're use case ideal view would be WebView.

It is easier to handle HTML in a webview rather than TextView.

TextView requires you to make use of spans for handling HTML content which is somewhat difficult when compared to handling HTML in a WebView.

And also for monitoring the scrolling behaviour, we can make use of the scroll event of an element in a webview which makes it easier to handle individual elements scroll behaviour.

So in order to make certain portions of text clickable make use of the below code snippet (Kotlin),

val htmlString = "<div>Handling the click near the specified indices</div>"         val document = Jsoup.parse(htmlString)         document.outputSettings().prettyPrint(false)         var plaintext = document.body().text()         plaintext = plaintext.replaceRange(13,18, "<a href='https://www.google.com'>${plaintext.substring(13, 18)}</a>")         document.body().html(plaintext) 

Make use of Jsoup library for parsing through the HTML content. The above code snippet will make the indexed substring clickable and point it to www.google.com. You can also add other events to it as well.

Then in order to check if an element is visible on screen you can have a javascript function like,

function isElementVisible(element)  {    var docViewTop = $(window).scrollTop();    var docViewBottom = docViewTop + $(window).height();          var elemTop = $(element).offset().top;    var elemBottom = elemTop + $(element).height();          return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

which takes in the element and returns true if element is visible onscreen or false if the element is not visible.

Answers 5

You can do that with SpannableString - find every link tags in your html text and set spannable wherever you need (for example for every between tag: SPANNABLE STRING).

Follow this topic, make your clickable spannable strings and show it in TextView. It's not so hard :)

Android: ClickableSpan in clickable TextView

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment