Android Question Notes app editing problem

AdrianZarr

New Member
in the note editor
when keyboard opens, some bottom text gets hidden behind the keyboard and i cant scroll it to view in order to see and edit it at all
i tried to use something like
Private Sub kb_HeightChanged (NewHeight As Int, OldHeight As Int)

but it never work

this is my current code

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private sv As ScrollView
    Private svEditor As ScrollView
    Private pnlEditorInner As B4XView
    Private pnlContent As B4XView
    Private nav As NavigationBar
    Private kb As IME
    
    ' Data Storage
    Private NotesList As List
    Private Const FILE_NAME As String = "user_notes.json"
    
    ' Editor UI
    Private pnlEditor As B4XView
    Private etTitle As EditText
    Private etBody As EditText
    Private CurrentIndex As Int = -1 ' -1 for new note
    
    ' Constants
    Private Const COLOR_PRIMARY As Int = 0xFF2196F3
    Private Const COLOR_BG As Int = 0xFFF0F2F5
End Sub

Public Sub Initialize As Object
    Return Me
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.Color = COLOR_BG
    B4XPages.SetTitle(Me, "Clinical Notes")
    
    ' Initialize Navigation
    nav.Initialize(Root, "Notes")
    kb.Initialize("kb")
    kb.AddHeightChangedEvent
    
    ' Initialize main ScrollView for rows
    sv.Initialize(1000)
    Root.AddView(sv, 0, 0, Root.Width, Root.Height - nav.NAV_HEIGHT)
    pnlContent = sv.Panel
    
    ' Setup components
    CreateEditorUI
    CreateFAB
    
    ' Load existing data
    LoadNotes
    RefreshNoteRows
End Sub

Private Sub B4XPage_Disappear
    ' Reset the page state only when NAVIGATING away, not when the screen turns off.
    ' Sleep(0) allows the B4XPages manager to update the internal stack first.
    Sleep(0)
    Dim TopPage As B4XPageInfo = B4XPages.GetManager.GetTopPage
    If TopPage = Null Or TopPage.B4XPage <> Me Then
        sv.ScrollPosition = 0
    End If
End Sub

' Intercept hardware back button to close editor instead of the app
Private Sub B4XPage_CloseRequest As ResumableSub
    If pnlEditor.IsInitialized And pnlEditor.Visible Then
        btnSave_Click ' Auto-save on back
        Return False
    End If
    Return True
End Sub

Private Sub CreateFAB
    Dim pnlFAB As B4XView = xui.CreatePanel("btnFAB")
    ' Position FAB above the bottom navigation bar
    Root.AddView(pnlFAB, Root.Width - 76dip, Root.Height - nav.NAV_HEIGHT - 76dip, 56dip, 56dip)
    pnlFAB.SetColorAndBorder(COLOR_PRIMARY, 0, 0, 28dip)
    UIEffects.SetCircleRipple(pnlFAB)
    
    Dim lbl As Label : lbl.Initialize("")
    Dim xlbl As B4XView = lbl
    xlbl.Text = Chr(0xE145) ' Material Add Icon
    xlbl.Font = xui.CreateMaterialIcons(28)
    xlbl.TextColor = xui.Color_White
    xlbl.SetTextAlignment("CENTER", "CENTER")
    pnlFAB.AddView(xlbl, 0, 0, 56dip, 56dip)
End Sub

Private Sub CreateEditorUI
    ' Full screen editor panel
    pnlEditor = xui.CreatePanel("pnlEditor")
    pnlEditor.Color = xui.Color_White
    pnlEditor.Visible = False
    Root.AddView(pnlEditor, 0, 0, Root.Width, Root.Height)
    
    ' Top Toolbar for Editor
    Dim pnlToolbar As B4XView = xui.CreatePanel("")
    pnlToolbar.Color = xui.Color_White
    pnlEditor.AddView(pnlToolbar, 0, 0, Root.Width, 60dip)
    
    ' Back button (Save & Exit)
    Dim lblBack As Label : lblBack.Initialize("btnSave")
    Dim xBack As B4XView = lblBack
    xBack.Text = Chr(0xE5C4) : xBack.Font = xui.CreateMaterialIcons(24)
    xBack.TextColor = COLOR_PRIMARY : xBack.SetTextAlignment("CENTER", "CENTER")
    pnlToolbar.AddView(xBack, 5dip, 5dip, 50dip, 50dip)
    UIEffects.SetCircleRipple(xBack)
    
    ' Delete button
    Dim lblDel As Label : lblDel.Initialize("btnDelete")
    Dim xDel As B4XView = lblDel
    xDel.Text = Chr(0xE872) : xDel.Font = xui.CreateMaterialIcons(24)
    xDel.TextColor = 0xFFFF5252 : xDel.SetTextAlignment("CENTER", "CENTER")
    pnlToolbar.AddView(xDel, Root.Width - 55dip, 5dip, 50dip, 50dip)
    UIEffects.SetCircleRipple(xDel)
    
    ' Add a thin divider at the bottom of the toolbar to tightly separate it from content
    Dim pnlDiv As B4XView = xui.CreatePanel("")
    pnlDiv.Color = 0xFFEEEEEE
    pnlToolbar.AddView(pnlDiv, 0, 59dip, Root.Width, 1dip)
    
    ' Input Fields
    ' Scrollable container for both title and body content
    svEditor.Initialize(1000)
    pnlEditor.AddView(svEditor, 0, 60dip, Root.Width, Root.Height - 60dip)
    pnlEditorInner = svEditor.Panel
    
    etTitle.Initialize("etTitle")
    etTitle.Hint = "Title"
    etTitle.Typeface = Typeface.DEFAULT_BOLD ' Keep bold for emphasis
    etTitle.TextSize = 24 ' Increased text size for a more prominent title
    etTitle.Color = xui.Color_Transparent
    etTitle.SingleLine = False
    etTitle.Gravity = Gravity.TOP
    etTitle.Padding = Array As Int(5dip, 5dip, 5dip, 0)
    ' Position at 0dip to eliminate the gap between toolbar and content
    pnlEditorInner.AddView(etTitle, 20dip, 0dip, Root.Width - 40dip, 50dip)
    
    etBody.Initialize("etBody")
    etBody.Hint = "Start typing..."
    etBody.TextSize = 18
    etBody.Color = xui.Color_Transparent
    etBody.SingleLine = False
    etBody.Gravity = Gravity.TOP
    ' Anchor Body at 0dip to keep the scroll position fixed
    pnlEditorInner.AddView(etBody, 20dip, 0dip, Root.Width - 40dip, 200dip)
    ' Keep Title in front of Body so both are clickable and the title stays visible
    etTitle.BringToFront


End Sub

Private Sub RefreshNoteRows
    pnlContent.RemoveAllViews
    Dim TopPos As Int = 15dip
    
    If NotesList.Size = 0 Then
        Dim lbl As Label : lbl.Initialize("")
        Dim xlbl As B4XView = lbl
        xlbl.Text = "No notes yet. Tap + to create one."
        xlbl.TextColor = 0xFF9E9E9E
        xlbl.SetTextAlignment("CENTER", "CENTER")
        pnlContent.AddView(xlbl, 20dip, 100dip, Root.Width - 40dip, 40dip)
        Return
    End If
    
    For i = 0 To NotesList.Size - 1
        Dim m As Map = NotesList.Get(i)
        Dim card As B4XView = xui.CreatePanel("NoteCard")
        card.Tag = i
        card.Color = xui.Color_White
        
        ' Extract specific lines to avoid list clutter
        Dim rawTitle As String = m.GetDefault("Title", "Untitled")
        If rawTitle = "" Then rawTitle = "Untitled"
        Dim tLines() As String = Regex.Split("\n", rawTitle)
        
        Dim rawBody As String = m.GetDefault("Body", "")
        Dim bLines() As String = Regex.Split("\n", rawBody)
        Dim bodySnippet As String = ""
        If bLines.Length > 0 Then
            bodySnippet = bLines(0)
            If bLines.Length > 1 Then bodySnippet = bodySnippet & CRLF & bLines(1)
        End If
        
        ' Title
        Dim lblT As Label : lblT.Initialize("")
        lblT.SingleLine = True ' Strictly one line horizontally
        Dim xlblT As B4XView = lblT
        xlblT.Text = tLines(0)
        xlblT.Font = xui.CreateDefaultBoldFont(16)
        xlblT.TextColor = 0xFF212121
        card.AddView(xlblT, 15dip, 12dip, Root.Width - 60dip, 25dip)
        
        ' Preview snippet
        Dim lblP As Label : lblP.Initialize("")
        Dim xlblP As B4XView = lblP
        xlblP.Text = bodySnippet
        xlblP.Font = xui.CreateDefaultFont(14)
        xlblP.TextColor = 0xFF757575
        card.AddView(xlblP, 15dip, 40dip, Root.Width - 60dip, 40dip)
        
        pnlContent.AddView(card, 10dip, TopPos, Root.Width - 20dip, 90dip)
        card.SetColorAndBorder(xui.Color_White, 0, 0, 8dip)
        UIEffects.SetRectangleRipple(card)
        
        TopPos = TopPos + 100dip
    Next
    
    pnlContent.Height = TopPos + 20dip
End Sub

Private Sub OpenEditor(Index As Int)
    CurrentIndex = Index
    If Index = -1 Then
        etTitle.Text = ""
        etBody.Text = ""
    Else
        Dim m As Map = NotesList.Get(Index)
        etTitle.Text = m.Get("Title")
        etBody.Text = m.Get("Body")
    End If
    UpdateEditorLayout
    pnlEditor.Visible = True
    
    ' Focus title if new note, otherwise body
    If Index = -1 Then
        etTitle.RequestFocus : kb.ShowKeyboard(etTitle)
    End If
End Sub

Private Sub kb_HeightChanged (NewHeight As Int, OldHeight As Int)
    If pnlEditor.IsInitialized And pnlEditor.Visible Then
        ' Adjust ScrollView height to the visible area above the keyboard
        ' We subtract 60dip which is the height of the editor's top toolbar
        svEditor.Height = Max(0, NewHeight - 60dip)
        UpdateEditorLayout
    End If
End Sub

Private Sub etBody_FocusChanged (HasFocus As Boolean)
End Sub

Private Sub UpdateEditorLayout
    Dim su As StringUtils
    ' Measure height needed for the title text given its current width
    Dim h As Int = su.MeasureMultilineTextHeight(etTitle, etTitle.Text & " W")
    ' Set Title height (no need to cap height now that it's in the ScrollView)
    etTitle.Height = Max(50dip, h + 10dip)
    
    ' Use Top Padding to offset the text relative to the Title
    Dim paddingTop As Int = etTitle.Height + 5dip
    etBody.Padding = Array As Int(2dip, paddingTop, 2dip, 2dip)
    
    ' Measure the height of the actual text
    Dim hB As Int = su.MeasureMultilineTextHeight(etBody, etBody.Text & " W")
    
    ' Use the current height of the scrollview (which is updated by kb_HeightChanged)
    Dim svEditorVisibleHeight As Int = svEditor.Height
    ' Set inner panel height to at least the visible scroll area, or larger if content demands it
    pnlEditorInner.Height = Max(svEditorVisibleHeight, paddingTop + hB + 20dip)
    
    ' Stretch the Body view to cover the entire scrollable area
    etBody.Height = pnlEditorInner.Height - etBody.Top
End Sub
''''' Event Handlers '''''

Private Sub btnFAB_Click
    OpenEditor(-1)
End Sub

Private Sub NoteCard_Click
    Dim p As B4XView = Sender
    OpenEditor(p.Tag)
End Sub

Private Sub etTitle_TextChanged (Old As String, New As String)
    UpdateEditorLayout
End Sub

Private Sub etBody_TextChanged (Old As String, New As String)
    UpdateEditorLayout
End Sub

Private Sub btnSave_Click
    Dim title As String = etTitle.Text.Trim
    Dim body As String = etBody.Text.Trim
    
    kb.HideKeyboard
    
    If title = "" And body = "" Then
        pnlEditor.Visible = False
        Return
    End If
    
    Dim m As Map
    If CurrentIndex = -1 Then
        m.Initialize
        NotesList.InsertAt(0, m) ' Newest first
    Else
        m = NotesList.Get(CurrentIndex)
    End If
    
    m.Put("Title", title)
    m.Put("Body", body)
    m.Put("Time", DateTime.Now)
    
    SaveNotes
    RefreshNoteRows
    pnlEditor.Visible = False
End Sub

Private Sub btnDelete_Click
    kb.HideKeyboard
    If CurrentIndex > -1 Then
        NotesList.RemoveAt(CurrentIndex)
        SaveNotes
        RefreshNoteRows
    End If
    pnlEditor.Visible = False
End Sub

''''' Data Persistence '''''

Private Sub SaveNotes
    Dim jgen As JSONGenerator
    jgen.Initialize2(NotesList)
    File.WriteString(xui.DefaultFolder, FILE_NAME, jgen.ToString)
End Sub

Private Sub LoadNotes
    NotesList.Initialize
    If File.Exists(xui.DefaultFolder, FILE_NAME) Then
        Try
            Dim parser As JSONParser
            parser.Initialize(File.ReadString(xui.DefaultFolder, FILE_NAME))
            NotesList = parser.NextArray
        Catch
            Log("Error loading notes: " & LastException)
        End Try
    End If
End Sub
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…