User Interface Question

TestMyChess

Member
Licensed User
Longtime User
Hi,

In my app I would like to display text such as "In the game White played Qd1-b3 (1 point). More usual is for White to carry on developing with e2-e3."

Ideally the user would then touch the Qd1-b3 and the program would display the position after that move.

Is this hyperlink-type behaviour achievable? I can't see how at the moment. If I had a button containing the "Qd1-d3" would it be possible to work out where the word "played" appears on the screen so that the button could be positioned after it?

Any suggestions for an alternative UI?

TIA

John
 

derez

Expert
Licensed User
Longtime User
You have not described where and how the text is displayed.
If it is in a messagebox, awaiting user response, then a customized message can be used, where you divide the text to first part, then there is the button underneath it, and under the button - the rest of the text. See this as an example. http://www.b4x.com/forum/additional...l-updates/24912-class-message.html#post144274

amother way, if the text is displayed on a label (maybe under the chess board ?) then you can use a click on the label, not specifically on the word, to launch the event.
 
Last edited:
Upvote 0

TestMyChess

Member
Licensed User
Longtime User
I imagine the text will be in a label, either under or to the right of the chess board. Allowing a click anywhere on the label is an idea, though the text may need to scroll on smaller devices, which might make this tricky.

Thanks

John
 
Upvote 0

TestMyChess

Member
Licensed User
Longtime User
Thanks for that, Martin. Do you think there's any way that clicking the link could run an event in my code? It seems to be more for launching web sites, emails and the like.

John
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
It seems to be possible, have a look at this search: https://www.google.co.uk/search?q=android+clickable+text&ie=UTF-8&oe=UTF-8.

Formatting your text as HTML and making the clickable words into an HTML SPAN element is one option.
You can then make that SPAN clickable.
An example using java can be found here: Android: Launch activity from clickable text - Stack Overflow.

I doubt you can do that entirely using B4A though, it'd require a little java to be compiled into a library i think.

I'll wait and see if anyone else has (easier) suggestions, if not i'll try to find some time to write some java for you.

Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Here we have a working example...
I've created a new library object called LabelExtras:

LabelExtras
Version: 0.01
  • LabelExtras
    Events:
    • UnderlineSpanClick (SelectionStart As Int, SelectionEnd As Int)
    Methods:
    • SetClickableText (Label1 As TextView, HtmlString As String, EventName As String)
      Turns any <u> elements in HtmlString into clickable spans and sets HtmlString as the Label1 Text property.
      If a clickable span is clicked then the UnderlineSpanClick(SelectionStart As Int, SelectionEnd As Int) event is raised.

And some example B4A code:

B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim ClickableLabel As Label
   Dim LogLabel As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("Main")
   
   '   note that the SetClickableText method parses the String as HTML
   '   so if you try to use the CRLF constant in this String it will not create a new line
   '   instead the HTML <br> element can be used
   
   Dim HtmlString As String="<u>Any</u> text that you want to detect clicks on must be within an HTML <u>UNDERLINE</u> element, the UnderlineSpanClick event is passed SelectionStart and SelectionEnd parameters.<br>Click <u>HERE</u> to continue."
   
   Dim LabelExtras1 As LabelExtras
   LabelExtras1.SetClickableText(ClickableLabel, HtmlString, "ClickableLabel")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ClickableLabel_UnderlineSpanClick(SelectionStart As Int, SelectionEnd As Int)
   Dim LogText As StringBuilder
   LogText.Initialize
   LogText.Append("ClickableLabel_UnderlineSpanClick: "&DateTime.Now&CRLF)
   LogText.Append("SelectionStar="&SelectionStart&CRLF)
   LogText.Append("SelectionEnd="&SelectionEnd&CRLF)
   Dim ClickedText As String=GetClickedText(SelectionStart, SelectionEnd)
   LogText.Append("Clicked text='"&ClickedText&"'")
   LogLabel.Text=LogText.ToString
   
   If ClickedText="HERE" Then
      StartActivity(ActivityTwo)
   End If
End Sub

Sub GetClickedText(SelectionStart As Int, SelectionEnd As Int) As String
   Dim LabelText As String=ClickableLabel.Text
   Log("LabelText="&LabelText)
   Dim ClickedText As String
   '   i've put this code in a Try/catch block as i was getting an occasional exception with an invalid range
   '   will need to be debugged...
   Try
      ClickedText=LabelText.SubString2(SelectionStart, SelectionEnd)
   Catch
      ClickedText=LastException
   End Try
   Return ClickedText
End Sub

The library parses any HTML <u> elements into clickable spans, if the user clicks one of these clickable spans then the UnderlineSpanClick event is raised and passed the start and end index of the clicked text.

In tests i got an occasional error when clicking the first clickable span - the span that conatins the word 'Any'.
The error was an out of range exception where the SelectionStart was -1 and the SelectionEnd was 0.
In theory this shouldn't occur but it needs a little debugging.

You'll probably not be happy with the default HTML syle applied to the clickable spans - on my tablet they are a pretty unreadable light blue color.
Different devices will probably render the clickable spans differently so a solution is required.

Give the attched code a test and post with your results.

Martin.
 
Last edited:
Upvote 0

TestMyChess

Member
Licensed User
Longtime User
Works pretty much perfectly, though I agree that some way to select the link colour would be good. Thank you very much.

John Harbour
Bedford, UK
 
Upvote 0

TestMyChess

Member
Licensed User
Longtime User
Forgot to say. Ideally I would want the link text bold and not underlined, as in my original message. Possible?

John
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Forgot to say. Ideally I would want the link text bold and not underlined, as in my original message. Possible?

John

I'll take a look in the morning - it's nearly 11PM here in the UK and too late for me to write any more code today.

Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Here's an update where the library now makes HTML <b> elements clickable and raises a StyleSpanClick event.
The clickable text style is no longer updated - so it's not underlined and it's color is not changed.
I've added code to the library that checks the values of SelectionStart and SelectionEnd - if either of these are -1 then no event is raised. So there is no longer a need to wrap LabelText.SubString2 in a Try/Catch block.

LabelExtras
Version: 0.02
  • LabelExtras
    Events:
    • StyleSpanClick (SelectionStart As Int, SelectionEnd As Int)
    Methods:
    • SetClickableText (Label1 As TextView, HtmlString As String, EventName As String)
      Turns any <b> Style elements in HtmlString into clickable spans and sets HtmlString as the Label1 Text property.
      If a clickable span is clicked then the StyleSpanClick(SelectionStart As Int, SelectionEnd As Int) event is raised.

The example code is much the same as before, the HtmlString now using <b> instead of <u> and the Try/Catch removed:

B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim ClickableLabel As Label
   Dim LogLabel As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("Main")
   
   '   note that the SetClickableText method parses the String as HTML
   '   so if you try to use the CRLF constant in this String it will not create a new line
   '   instead the HTML <br> element can be used
   
   Dim HtmlString As String="<b>Any</b> text that you want to detect <i>clicks</i> on must be within an HTML <b>BOLD</b> element, the StyleSpanClick event is passed SelectionStart and SelectionEnd parameters.<br><br>Click <b>HERE</b> to continue."
   
   Dim LabelExtras1 As LabelExtras
   LabelExtras1.SetClickableText(ClickableLabel, HtmlString, "ClickableLabel")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ClickableLabel_StyleSpanClick(SelectionStart As Int, SelectionEnd As Int)
   Dim LogText As StringBuilder
   LogText.Initialize
   LogText.Append("ClickableLabel_StyleSpanClick: "&DateTime.Now&CRLF)
   LogText.Append("SelectionStart="&SelectionStart&CRLF)
   LogText.Append("SelectionEnd="&SelectionEnd&CRLF)
   Dim ClickedText As String=GetClickedText(SelectionStart, SelectionEnd)
   LogText.Append("Clicked text='"&ClickedText&"'")
   LogLabel.Text=LogText.ToString
   
   If ClickedText="HERE" Then
      StartActivity(ActivityTwo)
   End If
End Sub

Sub GetClickedText(SelectionStart As Int, SelectionEnd As Int) As String
   Dim LabelText As String=ClickableLabel.Text
   Log("LabelText="&LabelText)
   Return LabelText.SubString2(SelectionStart, SelectionEnd)
End Sub

Everything is hardcoded to do exactly as you want - with a little time and effort the libary could be made much more versatile and user configurable.
It could be configurable to make different HTML elements clickable instead of just the <b> element.

Martin.
 
Last edited:
Upvote 0

TestMyChess

Member
Licensed User
Longtime User
Thanks, Martin.
<font color=""green""><b>Qd1-b3</b></font>
gives me exactly what I wanted.

How about using some do-nothing tag (in this context) such as <span> to mark the clickable section? This would allow non-clickable bold text without needing to be user configurable.

But perfect for me as it stands.

Cheers

John Harbour
Bedford UK
 
Upvote 0
Top