Android Question ime_HeightChanged event makes panels disappear

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Adjusted this code:

https://www.b4x.com/android/forum/threads/b4x-xui-b4xdialog-custom-dialogs.99756/

So it can handle all I need. It all works well, except for the ime_HeightChanged event.
For some reason this makes my panels temporarily disappear. They are still visible on the screen,
but testing with IsInitialized produced False and Resize can't work.
Sub edtInput_Click runs just prior to the ime_HeightChanged event and in that Sub the panels
are still OK. Strangely when I try another event after the panels are gone, eg with
chkShowPW_Click the panels are fine again.

This is the full code of the adjusted class:

B4X:
'version 1.10
'Class module
'#RaisesSynchronousEvents: edtInput_TextChanged
Sub Class_Globals
 
 Private xui As XUI
 Private sUtils As StringUtils
 Private ime As IME
 
 Public ButtonHeight As Int = 42dip 'if we do 40 then underscore character won't show!
 Public ButtonWidth As Int
 Public bInput As Boolean
 Private bPassWord As Boolean
 Public bVerticalButtons As Boolean
 Public Base As B4XView
 Private miBackgroundColour As Int
 Private miBorderColour As Int
 Public miButtonsTextColour As Int
 Private miButtonsColour As Int
 Private mbHideCurrentScreen As Boolean
 
 Public ButtonsTextSize As Int = 18
 Private Background As B4XView
 Private BlurImageView As B4XView
 Public BlurBackground As Boolean
 Private BlurReduceScale As Int
 Private iButtonsToAdd As Int
 
 Private mParent As Activity
 Public mCSPrompt As CSBuilder
 Private pnlDialog As B4XView
 Private imgIcon As B4XView
 Private lblTitle As B4XView
 Private edtInput As B4XView
 Private chkShowPW As B4XView
 Private lblPrompt As B4XView
 Private cvs As B4XCanvas

End Sub

Public Sub Initialize
 
 If xui.IsB4i Then
  BlurBackground = False
  BlurReduceScale = 3
 Else If xui.IsB4J Then
  BlurBackground = True
  BlurReduceScale = 1
 Else If xui.IsB4A Then
  'BlurBackground = False
  BlurReduceScale = 1
 End If
 
 ime.Initialize("ime")
 ime.AddHeightChangedEvent
 
End Sub

Public Sub Close (iResult As Int)
 General.RunLog("Dialog.Close, iResult: " & iResult)
 CallSubDelayed2(Me, "CloseMessage", iResult)
 'bVisible = False
End Sub

'event handlers
'------------------------------------------------------------------------------------
Private Sub chkShowPW_Click()
 
 Dim edt As EditText
 
 General.RunLog("chkShowPW_Click, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized) ' True
 General.RunLog("chkShowPW_Click, Base.IsInitialized: " & Base.IsInitialized) ' True
 
 edt = edtInput
 chkShowPW.Visible = True
 edt.PasswordMode = (chkShowPW.Checked = False)
 
End Sub

Private Sub edtInput_TextChanged (Old As String, New As String)
 
 General.RunLog("edtInput_TextChanged, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized) ' True
 
 If Visible And bPassWord Then
  Dim Yes As B4XView = GetButton(xui.DialogResponse_Positive)
  Yes.Enabled = edtInput.Text.Length > 0
  If Yes.Enabled Then
   Yes.TextColor = miButtonsTextColour
  Else
   Yes.TextColor = Colors.RGB(128, 128, 128) 'better than light grey
  End If
 End If
 
End Sub

Private Sub ime_HandleAction As Boolean
 
 Dim e As EditText
 
 e = Sender
 
 General.RunLog("ime_HandleAction, e.Tag: " & e.Tag)
 
 If e.Tag = "edtInput" Then
  Close (DialogResponse.POSITIVE)
  General.RunLog("ime_HandleAction")
  Return False 'will close the keyboard
 End If
 
 Return False
 
End Sub

Public Sub Visible As Boolean
 
 General.RunLog("Visible, Base.IsInitialized: " & Base.IsInitialized)
 Return Background.IsInitialized And Background.Parent.IsInitialized  Or Base.IsInitialized And Base.Parent.IsInitialized
 'Return Base.IsInitialized And mParent.IsInitialized
 'Return bVisible
End Sub

Private Sub edtInput_Click
 
 General.RunLog("edtInput_Click, Base.IsInitialized: " & Base.IsInitialized) '>> True
 
End Sub

Private Sub ime_HeightChanged (NewHeight As Int, OldHeight As Int)
 
 General.RunLog("ime_HeightChanged, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized) '>> False
 General.RunLog("ime_HeightChanged, Base.IsInitialized: " & Base.IsInitialized) '>> False
 General.RunLog("ime_HeightChanged, NewHeight: " & NewHeight & ", OldHeight: " & OldHeight)
 
 'keyboard state
 If Visible Then
  Resize(100%x, NewHeight)
 End If

End Sub

Public Sub Resize (Width As Int, Height As Int)
 
 General.RunLog("Resize, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized)
 
 If mbHideCurrentScreen Then
  Background.SetLayoutAnimated(0, 0, 0, Width, Height)
  Base.SetLayoutAnimated(200, Background.Width / 2 - Base.Width / 2, Background.Height / 2 - Base.Height / 2, Base.Width, Base.Height)
 Else
  Base.SetLayoutAnimated(200, mParent.Width / 2 - Base.Width / 2, Height / 2 - Base.Height / 2, Base.Width, Base.Height)
 End If
 
 If xui.IsB4J Then
  UpdateBlur
 End If
 
End Sub

Private Sub Button_Click
 
 Dim b As B4XView = Sender
 General.RunLog("B4XDialog, Button_Click: " & b.Tag)
 Close(b.Tag)

End Sub

#if B4J
Private Sub Background_MouseClicked (EventData As MouseEvent)
 EventData.Consume
End Sub
#end if

Private Sub Background_Touch (Action As Int, X As Float, Y As Float)
 General.RunLog("Background_Touch, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized)
End Sub

Private Sub Base_Touch (Action As Int, X As Float, Y As Float)
 'adding this Sub stops the dialog touch triggering an ime keyboard move!
 '-----------------------------------------------------------------------
 General.RunLog("Base_Touch, pnlDialog.IsInitialized: " & pnlDialog.IsInitialized)
End Sub

'------------------------------------------------------------------------------------

Private Sub DrawRect(oCanvas As B4XCanvas, iTop As Int, iLeft As Int, iBottom As Int, iRight As Int, iColour As Int, fWidth As Float)
 
 '                X1 ,   Y1,   X2,     Y2
 oCanvas.DrawLine(iLeft, iTop, iRight, iTop, iColour, fWidth * 1dip)
 oCanvas.DrawLine(iRight, iTop, iRight, iBottom, iColour, fWidth * 1dip)
 oCanvas.DrawLine(iLeft, iBottom, iRight, iBottom, iColour, fWidth * 1dip)
 oCanvas.DrawLine(iLeft, iTop, iLeft, iBottom, iColour, fWidth * 1dip)
 
End Sub

'note that Parent is Activity
Public Sub Show (Parent As B4XView, _
     arrButtons() As Object, _
     strTitle As String, strInput As String, strPrompt As String, _
     iInputMode As Int, bBlurBackGround As Boolean, _
     iTitleColour As Int, iTitleTextColour As Int, iInputTextColour As Int, iInPutLines As Int, iPromptTextColour As Int, _
     iButtonsTextColour As Int, iButtonsColour As Int, iDialogColour As Int, _
     iBorderColour As Int, iBackgroundColour As Int, csPrompt As CSBuilder, _
     bHideCurrentScreen As Boolean) As ResumableSub
     
 '  iInputMode
 '-----------------------
 '-1 no inputbox
 '0  no passsword
 '1  password, not hidden
 '2  password, hidden
 
 Dim i As Int
 Dim bInputSingleLine As Boolean
 Dim fMaxButtonTextWidth As Float
 Dim fPreferredButtonWidth As Float = (Parent.Width - 20dip) / 4
 Dim arrButtonTextWidths(arrButtons.Length) As Float
 Dim bVerticalButtons As Boolean
 Dim edt As EditText 'as we need some properties not available with B4XView
 Dim img As ImageView 'as bitmap won't show properly otherwise
 Dim iInputHeight As Int
 Dim iPromptHeight As Int
 Dim iHeight As Int
 Dim iWidth As Int
 
 Log("start of Show")
 
 iButtonsToAdd = arrButtons.Length 'number of buttons to add
 mbHideCurrentScreen = bHideCurrentScreen
 mParent = Parent
 mCSPrompt = csPrompt
 
 If bBlurBackGround Then
  'as the background panel will hold the blurred screen image
  bHideCurrentScreen = True
 End If
 
 'remove any existing dialog
 If bHideCurrentScreen Then
  For Each v As B4XView In Parent.GetAllViewsRecursive
   If v.Tag <> Null And v.Tag = "b4xdialog_background" Then
    v.RemoveViewFromParent
    Exit
   End If
  Next
 Else
  For Each v As B4XView In Parent.GetAllViewsRecursive
   If v.Tag <> Null And v.Tag = "b4xdialog_Base" Then
    v.RemoveViewFromParent
    General.RunLog("Dialog.Show, removed Dialog")
    Exit
   End If
  Next
 End If
 
 'bVisible = False
 
 'set all the default parameters
 'could make a type for all the Show arguments,
 'but I think this is simpler
 '---------------------------------------------
 If iDialogColour = 0 Then
  If csPrompt.IsInitialized Then
   iDialogColour = Colors.White
  Else
   iDialogColour = Colors.RGB(255, 255, 100) 'light yellow
  End If
 End If
 
 If iBackgroundColour = 0 Then
  miBackgroundColour = Colors.White
 Else
  miBackgroundColour = iBackgroundColour
 End If
 
 If iTitleColour = 0 Then
  iTitleColour = iDialogColour
 End If
 
 If iTitleTextColour = 0 Then
  iTitleTextColour = Colors.Black
 End If
 
 If iInPutLines = 0 Then
  iInPutLines = 1
 Else
  If iInPutLines = 1 Then
   bInputSingleLine = True
  End If
 End If
 
 If iInputTextColour = 0 Then
  iInputTextColour = Colors.Black
 End If
 
 If iPromptTextColour = 0 Then
  iPromptTextColour = Colors.Black
 End If
 
 If iButtonsColour = 0 Then
  iButtonsColour = Colors.White
 End If
 
 If iButtonsTextColour = 0 Then
  iButtonsTextColour = Colors.RGB(255, 165, 0) 'orange
 End If
 
 If iBorderColour = 0 Then
  iBorderColour = Colors.RGB(255, 165, 0) 'orange
 End If
 
 #if B4J
  miBorderColour = 0xff000000
 #else
 miBorderColour = iBorderColour
 #end if
 
 miButtonsTextColour = iButtonsTextColour
 miButtonsColour = iButtonsColour
 
 'hide the keyboard
 If iInputMode = -1 Then
  ime.HideKeyboard
 End If
 
 'load the dialog and get all the views
 '-------------------------------------
 'Sleep(0) 'this is needed as otherwise next line won't run!!
 pnlDialog = xui.CreatePanel("")
 pnlDialog.Tag = "pnlDialog"
 pnlDialog.SetLayoutAnimated(0, 0, 0, Parent.Width - 20dip, 170dip)
 pnlDialog.LoadLayout("PasswordDialog")
 
 BlurBackground = bBlurBackGround
 
 'get all the button text widths, deals as well with linebreaks and csBuilder text
 '--------------------------------------------------------------------------------
 For i = 0 To iButtonsToAdd - 1
  arrButtonTextWidths(i) = General.GetTextWidth(Parent, CStr(arrButtons(i)), ButtonsTextSize, Null, 4)
 Next
 
 'get the maximum button text width
 For i = 0 To iButtonsToAdd - 1
  If arrButtonTextWidths(i) > fMaxButtonTextWidth Then
   fMaxButtonTextWidth = arrButtonTextWidths(i)
  End If
 Next
 
 'see if we need vertical buttons
 If fMaxButtonTextWidth * iButtonsToAdd + (iButtonsToAdd + 1) * 5dip + iButtonsToAdd * 4dip > Parent.Width - 20dip Then
  bVerticalButtons = True
 End If
 
 If bVerticalButtons Then
  ButtonWidth = fMaxButtonTextWidth + 20dip
 Else
  If fMaxButtonTextWidth < fPreferredButtonWidth - 4dip Then
   ButtonWidth = fPreferredButtonWidth
  Else
   'max button width for horizontal buttons
   ButtonWidth = (Base.Width - 10dip) / iButtonsToAdd - 2dip * (iButtonsToAdd -  1)
  End If 'If fMaxButtonTextWidth < fPreferredButtonWidth - 4dip
 End If
 
 'set control colours
 lblTitle.Color = iTitleColour
 lblTitle.TextColor = iTitleTextColour
 edtInput.TextColor = iInputTextColour
 
 'set controls visibility
 If csPrompt.IsInitialized Or strPrompt.Length > 0 Then
  lblPrompt.Visible = True
 Else
  lblPrompt.Visible = False
 End If
 
 If lblPrompt.Visible Then
  'set prompt text or csBuilder text
  If csPrompt.IsInitialized Then
   lblPrompt.Text = csPrompt
  Else
   lblPrompt.textcolor = iPromptTextColour
   General.RunLog("Dialog.Show, lblPrompt.textcolor: " & lblPrompt.TextColor)
   lblPrompt.Text = strPrompt
  End If
 End If
 
 '  iInputMode
 '-----------------------
 '-1 no inputbox
 '0  no passsword
 '1  password, not hidden
 '2  password, hidden
 If iInputMode > -1 Then
  edtInput.Visible = True
 Else
  edtInput.Visible = False
 End If
 
 If iInPutLines > 1 Then
  edtInput.SetTextAlignment("TOP", "LEFT")
 End If
 
 If iInputMode > 0 Then
  chkShowPW.Visible = True
  chkShowPW.Color = Colors.ARGB(0, 0, 0, 0) 'zero alpha, so transparent
  bPassWord = True
 Else
  chkShowPW.Visible = False
  bPassWord = False
 End If
 
 'set dialog controls size and position
 '-------------------------------------
 edt = edtInput
 img = imgIcon
 
 lblTitle.Width = pnlDialog.Width - 32dip
 
 If iInputMode > 0 Then
  edtInput.Width = pnlDialog.Width - 39dip
  chkShowPW.Left = edtInput.Left + edtInput.Width + 1dip
 Else
  edtInput.Width = pnlDialog.Width - 10dip
 End If
 
 lblPrompt.Width = pnlDialog.Width - 10dip
 lblTitle.Text = strTitle
 
 If iInputMode = -1 Then
  edt.Visible = False
  edt.Height = 0
 Else
  edt.Top = lblTitle.Top + lblTitle.Height + 5dip
  edtInput.SetColorAndBorder(Colors.White, 1dip, iBorderColour, 1dip)
  
  'may need to set a maximum height
  '--------------------------------
  If iInPutLines > 1 Then
   iInputHeight = GetInputHeightFromLines(iInPutLines)
   edtInput.SetTextAlignment("TOP", "LEFT")
  Else
   iInputHeight = sUtils.MeasureMultilineTextHeight(edt, strInput)
  End If
  
  edtInput.Height = iInputHeight + 4dip
  
  chkShowPW.Top = (edt.Top + edt.Height) - chkShowPW.Height
  edtInput.Text = strInput
  edt.PasswordMode = (iInputMode = 2)
 End If
 
 If csPrompt.IsInitialized Or strPrompt.Length > 0 Then
  lblPrompt.Visible = True
 Else
  lblPrompt.Visible = False
 End If

 img.Bitmap = General.bmpIcon32
 
 If iInputMode > 0 Then 'Password mode
  chkShowPW.Visible = True
  chkShowPW.Checked = (iInputMode = 1)
  bInputSingleLine = True
 Else
  chkShowPW.Visible = False
  edt.SingleLine = bInputSingleLine 'so we can specify this by setting iInputLines as 1
 End If
 
 If bInputSingleLine Then
  ime.AddHandleActionEvent(edtInput) 'so Done button on the keyboard will do same as OK dialog button
 End If
 
 edt.SingleLine = bInputSingleLine
 
 If lblPrompt.Visible Then
  If iInputMode > -1 Then
   lblPrompt.Top = edtInput.Top + edtInput.Height + 5dip
  Else
   lblPrompt.Top = lblTitle.Top + lblTitle.Height + 5dip
  End If
  
  If lblPrompt.Text.Length > 0 Then
   If csPrompt.IsInitialized Then
    iPromptHeight = sUtils.MeasureMultilineTextHeight(lblPrompt, csPrompt)
   Else
    iPromptHeight = sUtils.MeasureMultilineTextHeight(lblPrompt, lblPrompt.Text)
   End If
   General.RunLog("SetDialogControls, iPromptHeight: " & iPromptHeight)
   lblPrompt.Height = iPromptHeight
  End If
 End If
 
 General.RunLog("SetDialogControls, pnlDialog.Height: " & pnlDialog.Height)
 '------------------------------------------------------------------------------------
 
 'set dialog height
 '------------------------------------------------------------------------------------------------------
 Dim iButtonRows As Int
 
 If bVerticalButtons Then
  iButtonRows =  iButtonsToAdd
 Else
  iButtonRows = 1
 End If
 
 If lblPrompt.Visible Then
  pnlDialog.Height = lblPrompt.Top + lblPrompt.Height + 10dip + (ButtonHeight + 2dip) * iButtonRows
 Else
  If edtInput.Visible Then
   pnlDialog.Height = edtInput.Top + edtInput.Height + 10dip + (ButtonHeight + 2dip) * iButtonRows
  Else
   pnlDialog.Height = lblTitle.Top + lblTitle.Height + 10dip + (ButtonHeight + 2dip) * iButtonRows
  End If
 End If
 
 General.RunLog("SetDialogHeight, pnlDialog.Height: " & pnlDialog.Height)
 '---------------------------------------------------------------------------------------------------------
 
 If bHideCurrentScreen Then
  Dim Background As B4XView = xui.CreatePanel("background")
  
  Background.Tag = "b4xdialog_background"
  
  If BlurBackground Then
   Dim iv As ImageView
   iv.Initialize("")
   BlurImageView = iv
   Background.AddView(BlurImageView, 0, 0, Background.Width, Background.Height)
   Background.Color = xui.Color_Transparent
  Else
   Background.Color = miBackgroundColour
  End If
  
  #if B4A
  Dim p As Panel = Background
  p.Elevation = 4dip
  #End If
  
  Parent.AddView(Background, 0, 0, Parent.Width, Parent.Height)
  
  If BlurBackground Then
   UpdateBlur
  End If
 End If
 
 Base = xui.CreatePanel("Base")
 Base.Tag = "b4xdialog_Base"
 Base.SetColorAndBorder(iDialogColour, 1dip, miBorderColour, 1dip)
 Base.RequestFocus
 
 iHeight = pnlDialog.Height + 3dip + 3dip
 iWidth = pnlDialog.Width + 2dip
 
 'add the base panel to screen hiding panel or activity
 If bHideCurrentScreen Then
  Background.AddView(Base, Background.Width / 2 - iWidth / 2, Background.Height / 2 - iHeight / 2, iWidth, iHeight)
 Else
  Parent.AddView(Base, Parent.Width / 2 - iWidth / 2, Parent.Height / 2 - iHeight / 2, iWidth, iHeight)
 End If

 bInput  = iInputMode > -1
 'bVisible = True
 
 For i = 0 To iButtonsToAdd - 1
  CreateButton(CStr(arrButtons(i)), -1 - i)
 Next

 cvs.Initialize(pnlDialog)
 cvs.DrawLine(imgIcon.Left + img.Width + 10dip, imgIcon.Top + imgIcon.Height / 2, _
     pnlDialog.Width - 10dip, imgIcon.Top + imgIcon.Height / 2, Colors.Blue, 0.5dip)
 'cvs.Invalidate
 If iInputMode > 0 Then
  DrawRect(cvs, chkShowPW.Top + 2, chkShowPW.Left + 16, (chkShowPW.Top + chkShowPW.Height) - 2, (chkShowPW.Left + chkShowPW.Width) - 4, iBorderColour, 1)
 End If
 cvs.Invalidate
 
 Base.Visible = False
 'so pnlDialog gets added to the panel Base here. Could we do away with panel Base?
 '---------------------------------------------------------------------------------
 Base.AddView(pnlDialog, 1dip, 1dip, pnlDialog.Width, pnlDialog.Height)
 Base.SetVisibleAnimated(100, True)
 
 General.RunLog("Show, before Wait For CloseMessage, Base.IsInitialized: " & Base.IsInitialized)
 
 '>>>>>>>>>>>>>>>>>>>>>>
 General.RunLog("Dialog.Show, just before Wait For CloseMessage")
 Wait For CloseMessage (Result As Int)
 General.RunLog("Dialog.Show, just after Wait For CloseMessage")
 '<<<<<<<<<<<<<<<<<<<<<<
 
 General.RunLog("Show, after Wait For CloseMessage, Base.IsInitialized: " & Base.IsInitialized)
 
 If bHideCurrentScreen Then
  For Each v As B4XView In Background.GetAllViewsRecursive
   General.RunLog("Dialog.Show, Background.GetAllViewsRecursive, v.Tag: " & v.Tag)
   v.Enabled = False
  Next
 Else
  For Each v As B4XView In Base.GetAllViewsRecursive
   General.RunLog("Dialog.Show, Base.GetAllViewsRecursive, v.Tag: " & v.Tag)
   v.Enabled = False
  Next
 End If

 Base.SetVisibleAnimated(100, False)
 
 Sleep(100) 'not sure this is needed
 
 If bHideCurrentScreen Then
  Background.RemoveViewFromParent
 Else
  Base.RemoveViewFromParent
 End If
 
 General.RunLog("Show, Base removed")
 General.RunLog("Show, Result: " & Result)
 
 If Result = xui.DialogResponse_Positive And bInput Then '-1
  Return edt.Text
 Else
  General.RunLog("Show, CStr(arrButtons(" & (Result * -1 - 1) & ")): " & CStr(arrButtons(Result * -1 - 1)))
  Return CStr(arrButtons(Result * -1 - 1))
 End If

End Sub

Private Sub GetInputHeightFromLines(iLines As Int) As Int
 
 Dim strLines As String
 Dim iHeight As Int
 
 strLines = General.MakeString(10, iLines - 1)
 iHeight = sUtils.MeasureMultilineTextHeight(edtInput, strLines)
 Return iHeight
 
End Sub

Private Sub CreateButton (Text As String, iCode As Int)
 
 Dim btn As Button
 Dim iLeft As Int
 Dim iButtonDistance As Int
 
 #if B4i
 btn.Initialize("Button", btn.STYLE_SYSTEM)
 #else
 btn.Initialize("Button")
 #End If
 
 If bVerticalButtons Then
  btn.Padding = Array As Int(4dip, 0, 4dip, 0)
 End If
 
 Dim xbtn As B4XView = btn
 
 xbtn.Text = Text
 xbtn.Tag = iCode
 xbtn.SetColorAndBorder(miButtonsColour, 0dip, miBorderColour, 2dip)
 xbtn.TextColor = miButtonsTextColour
 xbtn.Font = xui.CreateDefaultFont(ButtonsTextSize)
 
 If bVerticalButtons Then
  xbtn.SetTextAlignment("CENTER", "LEFT")
 Else
  xbtn.SetTextAlignment("CENTER", "CENTER")
 End If
 
 Dim iButtons As Int = Base.NumberOfViews 'nothing was added yet except of buttons
 
 General.RunLog("CreateButton, iButtons: " & iButtons)
 
 If bVerticalButtons Then
  Base.AddView(xbtn, 5dip, Base.Height - ((iButtonsToAdd - iButtons)) * (ButtonHeight + 4dip) , ButtonWidth, ButtonHeight)
 Else
  If iButtons = 0 Then
   iLeft = 5dip
  Else
   iButtonDistance = (Base.Width - ButtonWidth - 10dip) / (iButtonsToAdd - 1)
   General.RunLog("CreateButton2, iButtonDistance: " & iButtonDistance)
   iLeft = 5dip + iButtonDistance * iButtons + 1
   General.RunLog("CreateButton2, iButtonsToAdd - iButtons: " & (iButtonsToAdd - iButtons))
   General.RunLog("CreateButton2, iLeft: " & iLeft)
  End If
  Base.AddView(xbtn, iLeft, Base.Height - ButtonHeight - 4dip, ButtonWidth, ButtonHeight)
 End If
 
 If bInput Then
  Dim strOutput As String
  strOutput = edtInput.Text
 End If
 
 If iCode = xui.DialogResponse_Positive And bPassWord Then
  If strOutput.Length = 0 Then
   'this is needed as .Enabled = False doesn't make it look disabled
   xbtn.TextColor = Colors.RGB(128, 128, 128)
   xbtn.Enabled = False
  End If
 End If
 
 If strOutput.Length = 0 And bInput Then
  edtInput.RequestFocus
 Else
  If iCode = xui.DialogResponse_Cancel Then
   xbtn.RequestFocus 'does this do anything useful?
  End If
 End If

End Sub

'Returns one of the Yes, No or Cancel buttons.
Public Sub GetButton (ResultCode As Int) As B4XView
 
 For Each b As B4XView In Base.GetAllViewsRecursive
  If b.Tag = ResultCode Then Return b
 Next
 Return Null
 
End Sub

Private Sub UpdateBlur
 
 If BlurBackground = False Then Return
 Background.Visible = False
 Dim source As B4XBitmap = Background.Parent.Snapshot
 If source.Width > Background.Width Or source.Height > Background.Height Then
  source = source.Crop(0, 0, Background.Width, Background.Height)
 End If
 Background.Visible = True
 BlurImageView.SetLayoutAnimated(0, 0, 0, Background.Width, Background.Height)
 Dim blurred As BitmapCreator = Blur(source)
 blurred.SetBitmapToImageView(blurred.Bitmap, BlurImageView)
 
End Sub

Private Sub Blur (bmp As B4XBitmap) As BitmapCreator
 
 Dim n As Long = DateTime.Now
 Dim bc As BitmapCreator
 Dim ReduceScale As Int = BlurReduceScale
 bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
 bc.CopyPixelsFromBitmap(bmp)
 Dim count As Int = 2
 Dim clrs(3) As ARGBColor
 Dim temp As ARGBColor
 Dim m As Int
 
 For steps = 1 To count
  For y = 0 To bc.mHeight - 1
   For x = 0 To 2
    bc.GetARGB(x, y, clrs(x))
   Next
   SetAvg(bc, 1, y, clrs, temp)
   m = 0
   For x = 2 To bc.mWidth - 2
    bc.GetARGB(x + 1, y, clrs(m))
    m = (m + 1) Mod 3
    SetAvg(bc, x, y, clrs, temp)
   Next
  Next
  For x = 0 To bc.mWidth - 1
   For y = 0 To 2
    bc.GetARGB(x, y, clrs(y))
   Next
   SetAvg(bc, x, 1, clrs, temp)
   m = 0
   For y = 2 To bc.mHeight - 2
    bc.GetARGB(x, y + 1, clrs(m))
    m = (m + 1) Mod 3
    SetAvg(bc, x, y, clrs, temp)
   Next
  Next
 Next
 Log("Time: " & (DateTime.Now - n))
 Return bc
 
End Sub

Private Sub SetAvg(bc As BitmapCreator, x As Int, y As Int, clrs() As ARGBColor, temp As ARGBColor)
 
 temp.Initialize
 For Each c As ARGBColor In clrs
  temp.r = temp.r + c.r
  temp.g = temp.g + c.g
  temp.b = temp.b + c.b
 Next
 temp.a = 255
 temp.r = temp.r / 3
 temp.g = temp.g / 3
 temp.b = temp.b / 3
 bc.SetARGB(x, y, temp)
 
End Sub

Sub CStr(o As Object) As String
 Return "" & o
End Sub

This is in the manifest:

'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136

AddManifestText(
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="26"/>
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
SetApplicationAttribute(android:supportsRtl, "true")
'End of default text.

SetApplicationAttribute(android:theme, "@style/MyAppTheme")
SetActivityAttribute(Main, android:windowSoftInputMode, adjustResize)

CreateResource(values, themes.xml,
<resources>
<dimen name="action_button_padding">0dp</dimen>
<style name="MyAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#FF9800</item>
<item name="colorPrimaryDark">#F57C00</item>
<item name="colorAccent">#FFA726</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:actionButtonStyle">@style/ActionButton</item>
<item name="android:listPreferredItemHeightSmall">30dp</item>

</style>
<style name="ActionButton" parent="@android:style/Widget.ActionButton">
<item name="android:paddingStart">0dp</item>
<item name="android:paddingEnd">2dp</item>
<item name="android:minWidth">2dp</item>
<item name="android:drawablePadding">@dimen/action_button_padding</item>
</style>
</resources>

)


RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
You are posing too much code for it to be useful.

I recommend you to use XUI Views library. The latest version of B4XDialog is included there.
Check the example and see how the "time dialog" is created at the top of the screen.

You can do a similar thing with a custom dialog by setting B4XDialog.PutAtTop to true.

Thanks, will have a look at that XUI Views library.
I have in the meantime found the problem and fixed it. I attached a demo project that shows the
problem and I am sure any experienced B4A coder will see what the problems was.

RBS
 

Attachments

  • AllPurposeDialog.zip
    23.1 KB · Views: 168
Upvote 0
Top