I think the absence of reply is a clue to the answer.
True justification, which adjusts intercharacter spacing, not just interword spacing, is no easy task. And for single lines, it doesn't make sense, hence the reason that the last line of a justified paragraph is (usually) not just justified.
I don't know. The second one looks plausible, but it'll take a more masterful wrapper than me to bring it to B4A.Please Is it possible to use the above solutions in B4A ?
Tank you "Brandsum" for the answer.You can use a contenteditable div inside a webview.
I don't know. The second one looks plausible, but it'll take a more masterful wrapper than me to bring it to B4A.
It is somewhat foreboding that all those references refer to TextView, not EditText. Yes, I understand that Android's TextView supports editing, and had interword justification added a while back, but... posts by people trying to use both those features simultaneously do not instill optimism.
It sounds like you are heading towards wanting a WYSIWYG word processor, so I had a quick look at the add-on treasure map:
B4X Goodies
and these two looked promising:
https://www.b4x.com/android/forum/threads/richeditor-view.66319/
https://www.b4x.com/android/forum/threads/justifytextview-wrapper.55330/
but... no: richeditor seems to do alignment but not justification, and justifytextview seems to do (interword) justification but not editing.
A longer look covering less-obvious matches in the B4XGoodies list might uncover something that does both.
If you don't find that, then an alternative might be to superimpose a justifytextview on top of an EditText, where if you click (or long-click) on it, it "changes" to an EditText (by bringing the EditText to the top, or disabling/enabling appropriately) so that the user can edit the text, and then upon losing focus, reverts back to the justifytextview (with the newly-changed text loaded, obviously ;-)
sv.Panel.LoadLayout("Layout1")
I don't know. The second one looks plausible, but it'll take a more masterful wrapper than me to bring it to B4A.
It is somewhat foreboding that all those references refer to TextView, not EditText. Yes, I understand that Android's TextView supports editing, and had interword justification added a while back, but... posts by people trying to use both those features simultaneously do not instill optimism.
It sounds like you are heading towards wanting a WYSIWYG word processor, so I had a quick look at the add-on treasure map:
B4X Goodies
and these two looked promising:
https://www.b4x.com/android/forum/threads/richeditor-view.66319/
https://www.b4x.com/android/forum/threads/justifytextview-wrapper.55330/
but... no: richeditor seems to do alignment but not justification, and justifytextview seems to do (interword) justification but not editing.
A longer look covering less-obvious matches in the B4XGoodies list might uncover something that does both.
If you don't find that, then an alternative might be to superimpose a justifytextview on top of an EditText, where if you click (or long-click) on it, it "changes" to an EditText (by bringing the EditText to the top, or disabling/enabling appropriately) so that the user can edit the text, and then upon losing focus, reverts back to the justifytextview (with the newly-changed text loaded, obviously ;-)
#Region Project Attributes
#ApplicationLabel: LibEx
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Dim From As String
Private MyView As JustifyTextView
Dim sv As ScrollView
Private btn1 As Button
Private btn2 As Button
End Sub
Sub Activity_Create(FirstTime As Boolean)
'Do not forget to load the layout file created with the visual designer. For example
sv.Initialize(1900dip)
Activity.AddView(sv,0,0,100%x,300%y)
sv.Panel.LoadLayout("Layout1")
If File.Exists(File.DirInternal,"from.txt") = False Then
File.Copy(File.DirAssets,"from.txt",File.DirInternal,"from.txt")
End If
From = File.ReadString(File.DirInternal, "from.txt")
MyView.SetText(From,False)
'MyView.TextSize = 10
MyView.JustifyTextColor = Colors.Cyan
MyView.setPadding(10,10,10,10)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub btn2_Click
MyView.JustifyTextColor = Colors.Red
MyView.SetText(From,False)
End Sub
Sub btn1_Click
MyView.JustifyTextColor = Colors.Yellow
MyView.SetText(From,True)
End Sub
Delete the buttons from the layout.All Layout is scrollable in justifytextview (also buttons)
And I do not know how to scroll only text in justifytextview and no buttons.
Thank you "emexies" for quick answer.Delete the buttons from the layout.
Delete the .Click Subs too if you wish (no matter if you leave them in, though, because the buttons that called them no longer exist)
In the Activity_Create Sub, change the MyView.SetText second parameter from False to True
I don't know what the file-copying is about, why it doesn't just read from the Dir.Assets version, but presumably there is a reason. You could experiment with simplifying that bit of the example too, if you wish. If it turns out there is a reason for the file copying, I'd be interested to know what it was.
sv.Panel.LoadLayout("Layout1")
Yeah, it's an awkward example to branch out from.How to escape :
when there are also Buttons, Labels not only justifytextview in the Layout1 ?B4X:sv.Panel.LoadLayout("Layout1")
Thank you Semen for the answer.Android 8+ supports justify
https://developer.android.com/reference/android/widget/TextView.html#setJustificationMode(int)
Done.Yeah, it's an awkward example to branch out from ... Hang on, I'll give the thing a burl here.
Well done "emexes".Done.
Don't know why background of ScrollView won't change by code. If you work that out, let me know. In the meantime, change it in Designer.
Inter-paragraph spacing varies between justified/ragged modes. Again, why, dunno. Pretty certain that JustifyTextView has a 100% moneyback guarantee, you might have to look into that.
Great! :-/ (and thank you for preemptively softening the blow )I apologize for my demand:
Only two problems :
My first tack here would be to calculate it based on average text size, eg:1) How to solve programaticaly Panel Hight depends on load text size ?
Yeah, good luck with this. Maybe CharSequences that decrease the font size of blank lines between paragraphs. Probably won't work, but you never know your luck in the big city. Or maybe there is a Unicode smaller-than-usual line break, same as there are smaller-than-usual spaces.2) Gaps between text sections (CRLF) seems to be little large.
Thank you very much "emexes".Great! :-/ (and thank you for preemptively softening the blow )
Good questions, too (sadly!)
My first tack here would be to calculate it based on average text size, eg:
NumCharsPerLine = MyView.Width / (TextSize * some_constant)
NumLines = MyText.Length / NumCharsPerLine
LineHeight = TextSize * another_constant
MyView.Height = NumLines * LineHeight
and then you can fold the constants and make it one calculation:
MyView.Height = NumLines * LineHeight
MyView.Height = (MyText.Length / NumCharsPerLine) * (TextSize * another_constant)
MyView.Height = (MyText.Length / (MyView.Width / (TextSize * some_constant)) * (TextSize * another_constant)
MyView.Height = MyText.Length / MyView.Width * TextSize / some_constant * TextSize * another_constant
MyView.Height = MyText.Length * TextSize * TextSize * amalgamated_constant / MyView.Width
Hopefully I haven't mucked that up. It looks right, because:
AverageCharArea = TextSize * TextSize * amalgamated_constant
Area = NumChars * AverageCharArea
Height = Area / Width
Probably best to add a bit of extra height, to allow for partial lines and/or text with lots of wide characters. Could either just add a fixed amount, or something based on TextSize, and/or increase amalgamated constant.
The second tack was going to be Snapshot the ScrollView Panel to an image, then scan the image pixels to find the bottom of the text, but... I was getting B4A and B4J mixed up, and I don't know how to do the Snapshot in B4A. If you find out, let me know. Or there is some multiline text height function, but I don't know how it will handle justified layout. Give it a go - worst that'll happen is it doesn't work.
Yeah, good luck with this. Maybe CharSequences that decrease the font size of blank lines between paragraphs. Probably won't work, but you never know your luck in the big city. Or maybe there is a Unicode smaller-than-usual line break, same as there are smaller-than-usual spaces.
(... wanders off to do internet search ...)
Check this out: http://www.unicode-symbol.com/u/008B.html
You can add it after each NewLine with:
MyView.SetText(MyText.Replace(Chr(10), Chr(10) & Chr(0x8B), False)
or maybe even replace the NewLines for the case where JustifyTextView is already adding blank space between paragraphs:
MyView.SetText(MyText.Replace(Chr(10), Chr(0x8B), True) 'I might have True and False around the wrong way (am away from test bench)
but no guarantees, I'm just tossing ideas into the mix that documention indicates should/could work.
Thank you Erel for the answer.If you don't need the text to be editable then you can use BCTextEngine. It supports justification.
Sub Globals
Private MyText As String
Private MyView As BBCodeView
Private TextEngine As BCTextEngine
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout1")
TextEngine.Initialize(Activity)
If File.Exists(File.DirInternal,"from.txt") = False Then
File.Copy(File.DirAssets,"from.txt",File.DirInternal,"from.txt")
End If
MyText = File.ReadString(File.DirInternal, "from.txt")
MyView.mBase.Color = Colors.LightGray ' Error Type does not match
MyView.mBase.TextSize = 18 ' Error Type does not match
MyView.mBase.TextColor = Colors.Black ' Error Type does not match
MyView.Padding.Left = 10 ' Error Type does not match
MyView.Padding.right = 10 ' Error Type does not match
MyView.mBase.SetColorAndBorder(Colors.Gray,1dip,Colors.Black,3dip) ' Without error but no effect
'I DO NOT KNOW HOW TO SET JUSTIFY ALIGNEMENT ?
MyView.Text = MyText ' Works fine text is loaded
End Sub
Erel,If you don't need the text to be editable then you can use BCTextEngine. It supports justification.
Sub Globals
Private MyText As String
Private MyView As BBCodeView
Private TextEngine As BCTextEngine
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout1")
TextEngine.Initialize(Activity)
If File.Exists(File.DirInternal,"from.txt") = False Then
File.Copy(File.DirAssets,"from.txt",File.DirInternal,"from.txt")
End If
MyText = File.ReadString(File.DirInternal, "from.txt")
MyView.mBase.Color = Colors.LightGray ' ERROR Type does not match
MyView.mBase.TextSize = 18 ' ERROR Type does not match
MyView.mBase.TextColor = Colors.Black ' ERROR Type does not match
MyView.mBase.SetColorAndBorder(Colors.Gray,1dip,Colors.Black,3dip) ' Without error but no effect
'I DO NOT KNOW HOW TO SET TEXT JUSTIFY ALIGNEMENT ?
MyView.Padding.Initialize(30dip, 30dip, 30dip, 30dip)
MyView.Text = MyText
End Sub