Android Tutorial Dialogs library 2017 - Custom dialogs and async methods

Discussion in 'Tutorials & Examples' started by Erel, Jun 1, 2017.

Thread Status:
Not open for further replies.
  1. Erel

    Erel Administrator Staff Member Licensed User

    Dialogs v4 is an extension to @agraham original dialogs library. It requires B4A v7+.

    [​IMG]

    The main changes are:

    - New CustomLayoutDialog which makes it easier to develop custom dialogs.
    - New ShowAsync methods for all dialogs except of CustomDialog and CustomDialog2.

    The ShowAsync methods behave similar to Msgbox2Async and the other internal async dialogs: DoEvents deprecated and async dialogs (msgbox)

    Example:
    Code:
    Dim cd As ColorDialog
    Dim sf As Object = cd.ShowAsync("Choose Color""Yes""Cancel""No"NullFalse)
    Wait For (sf) Dialog_Result(Result As Int)
    If Result = DialogResponse.POSITIVE Then
       
    Activity.Color = cd.RGB
    End If
    The async methods also include a Cancelable parameter that determines whether the dialog can be cancelled with the back key or a click outside of the dialog.
    There are also other small improvements in the async methods implementation.
    As explained in the tutorial about DoEvents, it is recommended to switch to the async methods.
    Do note that ShowAsync + Wait For behavior is not identical to the modal dialogs behavior. When Wait For is called, the code returns to the calling sub (if there is one). If you want that the calling sub will wait for the sub that shows the async dialog: https://www.b4x.com/android/forum/threads/b4x-resumable-subs-sleep-wait-for.78601/page-2#post-499130


    CustomLayoutDialog

    CustomLayoutDialog replaces CustomDialog and CustomDialog2. As it is a non-modal dialog, it is more powerful. You can handle events while the dialog is visible and manage the dialog itself.
    Note that CustomLayoutDialog is supported by Android 4+ (API 14+).

    Showing the dialog is done in two steps:

    1. Call ShowAsync and wait for Dialog_Ready event.
    2. Load the layout to the panel (or create it programmatically).

    The Dialog_Result event will be raised when the dialog is closed.

    You can close the dialog programmatically by calling CloseDialog with the result:
    Code:
    Dialog.CloseDialog (DialogResponse.POSITIVE)
    You can explicitly set the dialog's size by calling SetSize. You need to call it after calling ShowAsync and before the Dialog_Ready event.
    Note that the size set is the size of the dialog. The panel itself will be smaller. Use a layout with anchors to make sure that the layout adapts properly.

    Dialog.GetButton will return one of the dialogs buttons. It can be used to disable or enable a button.
    For example this code enables the OK button when all fields are non-empty.
    Code:
    Sub DialogAge_ItemClick (Position As Int, Value As Object)
       CheckAllFieldsValid
    End Sub

    Sub DialogLastName_TextChanged (Old As String, New As String)
       CheckAllFieldsValid
    End Sub

    Sub DialogFirstName_TextChanged (Old As String, New As String)
       CheckAllFieldsValid
    End Sub

    Sub CheckAllFieldsValid
       
    Dim valid As Boolean = DialogAge.SelectedIndex > 0 And DialogFirstName.Text.Length > 0 And DialogLastName.Text.Length > 0
       DetailsDialog.GetButton(
    DialogResponse.POSITIVE).Enabled = valid
    End Sub
    The example is attached.

    The library is available here: https://www.b4x.com/android/forum/threads/dialogs-library.6776

    Edit: Cross platform custom layout dialog based on XUI: https://www.b4x.com/android/forum/threads/99756/#content
     

    Attached Files:

    Last edited: Nov 26, 2018
  2. Erel

    Erel Administrator Staff Member Licensed User

    And now for something that I wanted to do for a long time. A dialog that closes automatically after a few seconds:

    [​IMG]

    The relevant code is:
    Code:
    Sub btnEnterDetails_Click
       
    Dim dialog As CustomLayoutDialog
       
    Dim sf As Object = dialog.ShowAsync("""Yes""Cancel""No"NullFalse)
       
    Wait For (sf) Dialog_Ready (DialogPanel As Panel)
     
       DialogPanel.LoadLayout(
    "DetailsDialog")
       
    Dim disable() As Boolean = Array As Boolean(False)
       AutoClose(dialog, lblSeconds, disable)
       
    Wait For (sf) Dialog_Result (Result As Int)
     
       disable(
    0) = True 'disable the AutoClose timer
       If Result = DialogResponse.POSITIVE Then
         
    '...
       End If
    End Sub

    Sub AutoClose (TimedDialog As CustomLayoutDialog, UpdateLabel As Label, Disable() As Boolean)
       UpdateLabel.Text = 
    9 '9 seconds
       Do While UpdateLabel.Text > 0
         Sleep(
    1000)
         
    'the timer was disabled
         If Disable(0) = True Then Return
         UpdateLabel.Text = 
    NumberFormat(UpdateLabel.Text - 100)
       
    Loop
       TimedDialog.CloseDialog(
    DialogResponse.CANCEL)
    End Sub
    The trick in this code is that the Disable variable is an array. This allows us to change the value that the AutoClose sub will see and disable the "timer" if the user already clicked on one of the buttons.
    Note that this AutoClose sub can serve multiple dialogs and a similar solution can be used in other cases where you want to wait for an event but also set a timeout.
     

    Attached Files:

    Last edited: Jun 1, 2017
    AnandGupta, stingrae, Beja and 20 others like this.
  3. Informatix

    Informatix Expert Licensed User

    ??? It was possible. My BetterDialogs lib has this feature.
     
    cimperia, Cableguy, Star-Dust and 5 others like this.
  4. Erel

    Erel Administrator Staff Member Licensed User

    Fixed.
     
    Johan Hormaza, MarcoRome and rscheel like this.
  5. moster67

    moster67 Expert Licensed User

    ?? What was fixed?
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    My incorrect statement that it was not possible before.
     
  7. Peter Simpson

    Peter Simpson Expert Licensed User

    Excellent, thank you @Erel...
     
  8. Jaames

    Jaames Active Member Licensed User

    Hi,

    First example from the OP on the device 720x1280 , dialog is showing incorrectly :
    Screenshot_2017-06-03-13-53-55.png

    if I change line :
    Code:
    Dim sf As Object = DetailsDialog.ShowAsync("Enter details""Ok""Cancel"""LoadBitmap(File.DirAssets, "form.png"), True)
    to:

    Code:
    Dim sf As Object = DetailsDialog.ShowAsync("Enter details""Ok""Cancel"""LoadBitmapSample(File.DirAssets, "form.png",20dip,20dip), True)
    then it is ok.

    Screenshot_2017-06-03-13-58-54.png
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    Jaames likes this.
  10. coder19075

    coder19075 New Member

    how do we make a dialog with a text input?
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    See the example in the first post.
     
  12. AscySoft

    AscySoft Active Member Licensed User

    why array of boolean and not simply a boolean var?
     
    Jaames likes this.
  13. Erel

    Erel Administrator Staff Member Licensed User

    Good question. The array allows us to pass the boolean value by reference. If it was a regular boolean variable then it wouldn't have been possible to later change it:
    Code:
    Sub DoSomething
       
    Dim disable As Boolean = False
       AutoClose(disable) 
    'this is exactly like passing AutoClose(False)
       disable = True 'the local disable variable is assigned a a new value. No relation to the local Disable variable of AutoClose.
    End Sub

    Sub AutoClose(Disable As Boolean)
       Sleep(
    5000)
       
    Log(Disable) 'always false
    End Sub
     
    Jaames likes this.
  14. Victoire

    Victoire New Member Licensed User

     
  15. Dey

    Dey Active Member Licensed User

    Hello
    How can i close a Sub (data processing end) Dialog,
    Example after I finished data processing

    Thank you as always for what you do
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    See the TimedDialogExample in the second post. It calls the CloseDialog method.
     
  17. Martin Fernandez

    Martin Fernandez Member Licensed User

    Hello

    How can I hide the keyboard after in Sub CheckAllFieldsValid Valid=true?
    Keyboard remains open after click ok

    Thanks

    This doesn't work

    Code:
    Sub CheckAllFieldsValid
        
    Dim valid As Boolean = DialogAge.SelectedIndex > 0 And EditText2.text.Length > 0
        DetailsDialog.GetButton(
    DialogResponse.POSITIVE).Enabled = valid
        
    If valid= True Then
            
    Dim Phone1 As Phone
            Phone1.HideKeyboard(
    Activity)
        
    End If
    End Sub
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    This is not the correct place to hide it as it will hide it while the user is typing.

    You should instead hide it after the user clicks on Ok:
    Code:
    Wait For (sf) Dialog_Result(res As Int)
    Sleep(
    50)
    Dim im As IME
    im.Initialize(
    "")
    im.HideKeyboard
     
    red30 likes this.
  19. Martin Fernandez

    Martin Fernandez Member Licensed User

    Thanks Erel

    It works!
     
  20. Roberto P.

    Roberto P. Well-Known Member Licensed User

    Hello to all
    I can not see a scrollview to let you see a dialogue with many fields I use to handle filters.

    Code:
    Dim sf As Object = DetailsDialog.ShowAsync("Filtri Anagrafiche""OK""Annulla"""LoadBitmap(File.DirAssets, "img/form_trasparent.png"), True)
      
        DetailsDialog.SetSize(
    100%x100%y)
          
        
    Wait For (sf) Dialog_Ready(pnl As Panel)
          
        
    'pnl.LoadLayout("frmFiltriAnagrafiche")
        pnl.AddView(msvFiltri, 0dip,0dip90%x, aMaxHeight )
        msvFiltri.Panel.LoadLayout(
    "frmFiltriAnagrafiche")
      
      
        
    Wait For (sf) Dialog_Result(res As Int)
    Does not scroll vertically ?!

    Where am I wrong?
    thanks
     
Thread Status:
Not open for further replies.
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