B4A Library RichString library.

This library contains RichString and RichStringBuilder objects. These objects are analogous to the normal String and StringBuilder. However RichStrings can contain formatting information that controls how they are drawn when used as the text in a View.

This library also contains a RichStringFormatter object. This object, once suitably initialised, will efficiently format RichStrings passed to it. For long strings that require many changes of format this is much more efficient than using the individual RichString formatting commands.


EDIT :- Version 1.1 posted. See post #8 for details.

EDIT :- Version 1.2 posted including RichStringFormatter. See post #13 for details.

EDIT :- Version 1.3 posted. See post #15 for details.

EDIT :- Version 1.4 posted. See post #56 for details.

EDIT (by Erel) :- Version 1.5: https://www.b4x.com/android/forum/threads/richstring-library.10680/page-6#post-475477
 

Attachments

  • RichString.zip
    11.6 KB · Views: 2,350
Last edited by a moderator:

Kamac

Active Member
Licensed User
Longtime User
Well,

rs.Initialize("This is not a RichString")
rs.Color(Colors.Red, 14, 18)

is actually hard to perform, because we have to count our letters to place the colored word. It takes time, and is very hard to do with dynamic text.


This solution:


rs.Initialize("This is not a $Rich$String")
rs.Color("$", Colors.Red, 14, 18)

would be way better, almost the same as:

rs.Initialize("This is not a <color 0xffff0000>Rich</color>String")
rs.Color(Colors.Red, 14, 18)
 

margret

Well-Known Member
Licensed User
Longtime User
Rich text


Hello, What about doing something like this as an idea:

rs.Initialize("This is not a RichString")
rs.Color(Colors.Red, "Rich", "String")


Do the equivalent to At(String) As INT, this way you don't have to count, it will be the same as: rs.Color(Colors.Red, 14, 18). Just a thought.

Thanks,

Margret
 

agraham

Expert
Licensed User
Longtime User
I like the XML/Html variant. I suggest to make the syntax as short as possible (<b>, <u>).
You could do something like that anyway with

rs.Initialize("This <u>is<u> not a RichString")
rs.Underscore2("<u>")

Which I implemented now anyway as it was dead easy. The real decision is to whether to stick to

rs.Initialize("This {R}is{R} not a {R}Rich{R}String")
rs.Color2(Colors.Red, "{R}")

or also implement

rs.Initialize("This <col 0xffff0000>is</col> not a <col 0xffff0000>Rich</col>String")
rs.Color2(Colors.Red, "{R}")

Which gets into XML parsing territory and is also possibly not as easy to use programmatically on dynamic strings. Thoughts?
 

margret

Well-Known Member
Licensed User
Longtime User
Rich String

Sorry for the previous suggestion. When I saw Erel's post, it just hit me about what you were doing. I think Erel's suggestion is best also. I much prefer this one:

rs.Initialize("This {R}is{R} not a {R}Rich{R}String")
rs.Color2(Colors.Red, "{R}")



Thanks,

Margret
 
Last edited:

ZJP

Active Member
Licensed User
Longtime User
B4X:
rs.Initialize("This is not a RichString")
rs.Color(Colors.Red, 14, 18)

+1

Edit : Tested. I like this lib. Thx.
 
Last edited:

moster67

Expert
Licensed User
Longtime User
Very nice Agraham. :sign0098:

For labels, it is perfect since mostly the text remains "static" and the text is populated by code.

Just for the fun of it, I tried it also in an EditText-view and the richtext-formatting works nicely there as well. It just gets tricky when you let the user insert and modify text but perhaps using the events of EditText, maybe one can come up with a solution. I will play with it later again and see if I can make a small notepad-application with Richtext-properties.

As always, thanks for your great work.
 

agraham

Expert
Licensed User
Longtime User
Version 1.2 now posted includes the RichStringFormatter object. I'm quite pleased with this.

RichStringFormatter lets you define your formatting tokens once and you can then use it time and time again to format RichStrings by just passing a RichString to it. This should make it much easier to program RichStrings whose formatting may be dynamically changed at runtime.
 

Djembefola

Active Member
Licensed User
Longtime User
Great Library

Thank you.

:sign0188:
 

agraham

Expert
Licensed User
Longtime User
Version 1.3 now posted has a couple of improvements.

Previously if you used an undefined token in the RichString passed to a RichStringFormatter your application would force close because the exception was raised on the rendering thread and not the main thread so it could not be caught. Now an explicit check is made for this and a new UnimplementedToken method will return an array of any such encountered while formatting.

A new format option, ScaleX, has been added as I overlooked it before. It expands or compresses text horizontally.
 
Last edited:

corwin42

Expert
Licensed User
Longtime User
I tried to use RichString formatting in a homescreen widget label but it does not work.

Am I right that it is because RemoteView.SetText() has a String type as second parameter so if I pass a RichString it will be converted to a normal String?

I think I currently have no chance to get it working?
 

agraham

Expert
Licensed User
Longtime User
The String type of the Text parameter will indeed be the problem. The underlying Android setTextViewText method does in fact take a CharacterSequence type so it could probably be made to work with the Reflection library. If you post a small project with a widget with a label showing your present attempt I'll see if I can modify it to work.
 

corwin42

Expert
Licensed User
Longtime User
Thanks very much, but...

B4X:
Compiling code.                         Error
Error compiling program.
Error description: Too many parameters.
Occurred on line: 40
args(1) = rsf.Format(rs, rsf.SPAN_INCLUSIVE_EXCLUSIVE) ' CharSequence
Word: rsf

New version of RichString Library?
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…