Android Question EditText - Justified Alignement

Discussion in 'Android Questions' started by js486dog, Sep 13, 2019 at 10:21 AM.

  1. js486dog

    js486dog Member Licensed User

    I can use Left, Right, Center Alignement in EditText.

    Please, is there some possibility to use also Justified Alignement in EditText ?
     

    Attached Files:

  2. emexes

    emexes Well-Known Member Licensed User

    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.
     
  3. js486dog

    js486dog Member Licensed User

    Thank you "emexes" for the answer.
    I need - multiline text to be aligned on both sides of EditText.


    I have found some solutions :

    https://github.com/ufo22940268/android-justifiedtextview
    https://github.com/navabi/JustifiedTextView
    https://stackoverflow.com/questions/44368339/justifying-text-inside-a-textview-in-android
    https://stackoverflow.com/questions/1292575/android-textview-justify-text

    But I do not know how to implement them in B4A.
    Please Is it possible to use the above solutions in B4A ?
     
  4. emexes

    emexes Well-Known Member Licensed User

    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 ;-)
     
  5. Brandsum

    Brandsum Active Member Licensed User

    You can use a contenteditable div inside a webview.
     
    emexes likes this.
  6. js486dog

    js486dog Member Licensed User

    Tank you "Brandsum" for the answer.
    I do not need webview. I need EditText.
     
  7. js486dog

    js486dog Member Licensed User

    Thank you "emexes".

    justifytextview would be fine for me but:
    All Layout is scrollable in justifytextview (also buttons)
    Code:
    sv.Panel.LoadLayout("Layout1")
    Look also b4aexample.zip :
    https://www.b4x.com/android/forum/threads/justifytextview-wrapper.55330/

    And I do not know how to scroll only text in justifytextview and no buttons.
     
  8. js486dog

    js486dog Member Licensed User

    Thank you "emexes".

    justifytextview would be fine for me but:
    All Layout is scrollable in justifytextview (also buttons)

    And I do not know how to scroll only text in justifytextview and no buttons.

    Code:
    #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
     
  9. emexes

    emexes Well-Known Member Licensed User

    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.

    :)
     
  10. js486dog

    js486dog Member Licensed User

    Thank you "emexies" for quick answer.

    I understand almost all in the code above (SetText, LoadText, ColorText , Dir.Assets ... ).

    Only one I do not understand:
    I need to have also the buttons or labels or another features in the Layout. But not scrollable.
    How to scroll only multiline text in justifytextview ?

    How to escape :

    Code:
    sv.Panel.LoadLayout("Layout1")
    when there are also Buttons, Labels not only justifytextview in the Layout1 ?
     
  11. emexes

    emexes Well-Known Member Licensed User

    Yeah, it's an awkward example to branch out from.

    What you would normally do is have all your fixed stuff on the layout, including the CLV view, and then add the JustifyTextView to the CLV. What I am mildly confused about is: doesn't the JustifyTextView already do scrolling itself? Presumably it does not, otherwise why does the example put it into a CLV?

    Hang on, I'll give the thing a burl here.
     
  12. Semen Matusovskiy

    Semen Matusovskiy Well-Known Member Licensed User

  13. js486dog

    js486dog Member Licensed User

  14. emexes

    emexes Well-Known Member Licensed User

    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.

    :)
     

    Attached Files:

    js486dog likes this.
  15. js486dog

    js486dog Member Licensed User

    Well done "emexes".
    Works fine.

    I have done some little amendments.

    I apologize for my demand:
    Only two problems :

    1)

    How to solve programaticaly Panel Hight depends on load text size ?

    sv.Panel.Height = 6000dip 'interior scroll panel height
    6000 is a lot for from.txt for text size >18
    3000 is small for from.txt for text size >18

    2)

    Gaps between text sections (CRLF) seems to be little large.
     

    Attached Files:

  16. emexes

    emexes Well-Known Member Licensed User

    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.

    :)
     
  17. js486dog

    js486dog Member Licensed User

    Thank you very much "emexes".
    I will try your suggestions.
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    If you don't need the text to be editable then you can use BCTextEngine. It supports justification.
     
  19. js486dog

    js486dog Member Licensed User

    Thank you Erel for the answer.

    I have tried it.
    I can load text into BBCodeView.

    But I do not know how to set programaticaly:

    color
    text size
    text color
    text justify alignement
    padding
    border color, border width, border radius

    of BBCodeView ?

    Please how can I do that ?

    Code:
    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
     
  20. js486dog

    js486dog Member Licensed User

    Erel,

    I have found padding.
    I can load text into BBCodeView.


    But I do not know how to set programaticaly:

    color
    text size
    text color
    text justify alignement
    border color, border width, border radius

    of BBCodeView ?


    Code:
    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(
    30dip30dip30dip30dip)
        MyView.Text = MyText


    End Sub
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice