B4A Library [Lib] BetterDialogs

I tried to improve the most useful dialogs of the Dialogs library. In my version, HTML tags are interpreted (even in the text of buttons), the InputBox uses a Masked EditText and has more options, you can check if the input is valid before closing the dialog, and the CustomDialog is fully customizable. I also solved an issue with the virtual keyboard.

MsgBox (under Gingerbread and JellyBean):

msgbox.png


InputBox (under Gingerbread and JellyBean):

inputbox.png


CustomDialog (under Gingerbread and JellyBean):

cd1.jpg


Another CustomDialog (under Gingerbread and JellyBean):

cd2.png


v1.1:
- I added a CloseDialog function;
- I added a margin parameter to the custom dialog.

v1.2:
- I fixed a bug in InputBox when there's a default value;
- I added the BackKeyPressed event for custom dialogs.

v1.3:
- I added a PasswordMode option to the InputBox;
- I added a CancelOnTouchOutside option.

v1.4:
- I added a CursorPosition option to the InputBox.

v2.0:
- I moved the CustomDialog parameters to the BD_CustomDlgParams class.
- I added two new parameters: Duration and DialogGravity.
- I removed the Margin parameter and added the MarginHeight parameter (to be used when Gravity is set to TOP).
- The BodyWidth and BodyHeight parameters defines now accurately the size of the dialog body.

v2.1:
- I added a "closing" event raised just before a custom dialog is dismissed. You can cancel the closure by returning False.

v2.11:
- I added the "DlgResponse" parameter to the Closing event.

This library does not work with Android versions < 2.
It requires another library: Masked EditText
 

Attachments

  • BetterDialogs v2.11.zip
    55.6 KB · Views: 2,238
  • Java source - BetterDialogs.zip
    8.5 KB · Views: 669
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
This question is related to the view that you use in your custom dialog, not the dialog itself, so I cannot give an answer.

Ah yes, good point. I can use the events of the views to validate their values. And I can try using MaskedEditText to show validation errors inline.

Idem. That concerns the IME or the view, not the dialog.

What I meant was the OK button of the custom dialog, which I don't see any library methods to access. Ideally, if any of the fields were missing or invalid, I would disable the OK button until they were valid. For now, I assume the OK button is always enabled, which means I need to handle whatever they enter, after the dialog closes.
 

Informatix

Expert
Licensed User
Longtime User
What I meant was the OK button of the custom dialog, which I don't see any library methods to access. Ideally, if any of the fields were missing or invalid, I would disable the OK button until they were valid. For now, I assume the OK button is always enabled, which means I need to handle whatever they enter, after the dialog closes.
Ah OK I understand. There's no simple mean to access/configure the default buttons so, if you create a custom dialog, I suggest that you add your own buttons at the bottom.
 

johndb

Active Member
Licensed User
Longtime User
In custom dialogs, is it possible to validate fields at the field level (e.g. lost focus) or before clicking OK?

Related question: Is it possible to enable/disable OK programmatically (e.g. if a field value is missing or not valid)?

Merci!
I am currently using XtraViews library for my dialog management and it has events that are triggered before a dialog is displayed and when a dialog is about to close. You can validate your field data in the dialog close event, display a message box if the data is invalid, and return a flag to cancel the dialog closure. I am using this feature regularly in my applications.

You can also disable buttons by passing a null string as a parameter thereby making them inactive.

I hope this helps,

John
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I am currently using XtraViews library for my dialog management and it has events that are triggered before a dialog is displayed and when a dialog is about to close. You can validate your field data in the form close event, display a message box if the data is invalid, and return a flag to cancel dialog closure. I am using this feature regularly in my applications.

You can also disable buttons by passing a null string as a parameter thereby making them inactive.

I hope this helps,

John
Ok, I understand now what was the need of Dave O. I completely missed the point. I will add a "Closing" event to BD.
 

Dave O

Well-Known Member
Licensed User
Longtime User
I added a "closing" event raised just before a custom dialog is dismissed. You can cancel the closure by returning False.

This event will make it much easier to validate input, thank you.

However, I would like Cancel to close the dialog without doing validation. Is it possible to pass this info in the event, so that we know which button was clicked? Something like:

B4X:
Sub customDialog_Closing(wasCanceled as boolean) As Boolean
if wasCanceled then
   return true   'allow the dialog to close regardless of validation
else
   if fieldsAreValid then  'my own boolean to track the validation state of the dialog
      return true
   else
      return false
   end if
end sub

You could also argue that Cancel should ALWAYS work, in which case the Closing event could be made to fire only when OK was pressed (in which case it would be good to rename the event to something like OkClicked).

Merci encore!
 

Informatix

Expert
Licensed User
Longtime User
This event will make it much easier to validate input, thank you.

However, I would like Cancel to close the dialog without doing validation. Is it possible to pass this info in the event, so that we know which button was clicked? Something like:

B4X:
Sub customDialog_Closing(wasCanceled as boolean) As Boolean
if wasCanceled then
   return true   'allow the dialog to close regardless of validation
else
   if fieldsAreValid then  'my own boolean to track the validation state of the dialog
      return true
   else
      return false
   end if
end sub

You could also argue that Cancel should ALWAYS work, in which case the Closing event could be made to fire only when OK was pressed (in which case it would be good to rename the event to something like OkClicked).

Merci encore!
Sorry but I don't understand the request. What do you mean by "without doing validation"? "Validation" is an event of InputBox. "Closing" is an event of CustomDialog. They cannot be fired by the same dialog. And what's the info I am supposed to pass to the event ("wascanceled"???)?
 

Dave O

Well-Known Member
Licensed User
Longtime User
Sorry but I don't understand the request. What do you mean by "without doing validation"? "Validation" is an event of InputBox. "Closing" is an event of CustomDialog. They cannot be fired by the same dialog. And what's the info I am supposed to pass to the event ("wascanceled"???)?

Sorry, let me try to explain better:

I have a CustomDialog with some data-entry fields (radio buttons and MaskedTextEdit). As the user enter values, I use the various view events to check the data and use ShowError messages where needed. That's all working well.

If the user clicks OK, I'm using the Closing event to check that the form is valid before closing the dialog. If any form fields are invalid, I return false and the dialog stays open. That's also working well.

If the user clicks Cancel, I want to throw away their changes and close the dialog. In this case, it doesn't matter that the form values may be invalid, because the user is not trying to save that data - they've decided to throw it away and dismiss the dialog.

The problem here is that when the Closing event fires, I don't know which button they pressed (Cancel or OK), so I don't know whether I should do the OK case (check the data and keep the dialog open if the validation fails) or the Cancel case (just close the dialog and forget the changes).

If the Closing event passed some information about which button was clicked, I could make the dialog behave as users expect. Without this information, the Closing event seems much less useful for dialogs used for data entry.

Thanks!
 

Informatix

Expert
Licensed User
Longtime User
Sorry, let me try to explain better:

I have a CustomDialog with some data-entry fields (radio buttons and MaskedTextEdit). As the user enter values, I use the various view events to check the data and use ShowError messages where needed. That's all working well.

If the user clicks OK, I'm using the Closing event to check that the form is valid before closing the dialog. If any form fields are invalid, I return false and the dialog stays open. That's also working well.

If the user clicks Cancel, I want to throw away their changes and close the dialog. In this case, it doesn't matter that the form values may be invalid, because the user is not trying to save that data - they've decided to throw it away and dismiss the dialog.

The problem here is that when the Closing event fires, I don't know which button they pressed (Cancel or OK), so I don't know whether I should do the OK case (check the data and keep the dialog open if the validation fails) or the Cancel case (just close the dialog and forget the changes).

If the Closing event passed some information about which button was clicked, I could make the dialog behave as users expect. Without this information, the Closing event seems much less useful for dialogs used for data entry.

Thanks!
Ok, understood. Good suggestion. I updated the library.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
I'm using the BackKeyPressed evtprefix, and now I'm getting errors when the back button is pressed

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
at flm.b4a.betterdialogs.BetterDialogs$2.onKey(BetterDialogs.java:808)
at android.app.Dialog.dispatchKeyEvent(Dialog.java:750)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2310)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4127)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4089)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5857)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6025)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

EDIT: Nvm, seems to be eliminated in the newer version. I wish B4A auto-updated libraries...
 
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
I'm trying to create a custom dialog that has a single field - a multi-line MaskedEditText that fills the dialog (for entering long notes).

I've created a layout for the field, with anchors set to BOTH with no margins. However, when I try to open the custom dialog, the field does not appear.

If I change the margins to 10, I get a small text field at the upper left.

Is it possible for me to have a text field the same size as the dialogPanel in the custom dialog?

Thanks!
 

Informatix

Expert
Licensed User
Longtime User
I'm trying to create a custom dialog that has a single field - a multi-line MaskedEditText that fills the dialog (for entering long notes).

I've created a layout for the field, with anchors set to BOTH with no margins. However, when I try to open the custom dialog, the field does not appear.

If I change the margins to 10, I get a small text field at the upper left.

Is it possible for me to have a text field the same size as the dialogPanel in the custom dialog?

Thanks!
Forget the anchors. Set the position and size with the old and reliable methods.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
For anchors to work the parent container size must be set before the call to LoadLayout. If you are loading the layout to a panel then you should first add the panel to a parent with the correct size and then load the layout.

If you don't have access to the parent then you can do something like:
B4X:
Dim p As Panel
p.Initialize("")
Activity.AddView(p, 0, 0, 300dip, 200dip)
p.LoadLayout(...)
p.RemoveView 'remove it from the activity
 

Dave O

Well-Known Member
Licensed User
Longtime User
Forget the anchors. Set the position and size with the old and reliable methods.

By "old and reliable methods", I assume you mean designer scripts. I tried this designer script in the layout (where noteField is the solitary text field):

B4X:
noteField.SetLeftAndRight(10dip, 100%x - 20dip)
noteField.SetTopAndBottom(10dip, 100%y - 20dip)

...and I have the dialog dimensions set like this:
B4X:
dialogParams.BodyWidth = 100%x - 30dip
dialogParams.BodyHeight = 100%y - 150dip

This works well, except that the text entry goes too close to the right edge, so I compensated by setting the padding on the text field (where SetPadding is a utility method that Erel describes elsewhere:

B4X:
setPadding(noteField, 0, 0, 10dip, 10dip)

Hope this helps!
 

Informatix

Expert
Licensed User
Longtime User
By "old and reliable methods", I assume you mean designer scripts. I tried this designer script in the layout (where noteField is the solitary text field):

B4X:
noteField.SetLeftAndRight(10dip, 100%x - 20dip)
noteField.SetTopAndBottom(10dip, 100%y - 20dip)

...and I have the dialog dimensions set like this:
B4X:
dialogParams.BodyWidth = 100%x - 30dip
dialogParams.BodyHeight = 100%y - 150dip

This works well, except that the text entry goes too close to the right edge, so I compensated by setting the padding on the text field (where SetPadding is a utility method that Erel describes elsewhere:

B4X:
setPadding(noteField, 0, 0, 10dip, 10dip)

Hope this helps!
No, I meant to set the position and size by code as you set the body width and height by code. It's a reliable method, with no surprise. You don't need to add a padding or use any trick. Example (add these lines to the demo after dlgParams.BodyWidth and dlgParams.BodyHeight):
B4X:
EditText1.Left = 5dip
EditText1.Width = dlgParams.BodyWidth - 10dip
 

Harris

Expert
Licensed User
Longtime User
Here is a weird one...

This view is on a Samsung Active 8 (inch) tablet running Android version 5.1.1.
Everything is perfect with dialog in my TripInspect app.

bd3_.png



This view is on the same device in a different app (Punch Clock). I had to pad the Yes / No buttons to make them look reasonable, otherwise they are small and pushed to either end of box.

bd1_.png


This view is on an Acer 8 (inch) with the same app, running 4.4.4 kitkat.
Everything is fine (where not so good on Samsung Active 8 and LG3 phone)...

bd2_.png


WTF is happening here? I am (as per usual) lost...

Here is my code module...

Thanks


B4X:
'Code module
'Subs in this code module will be accessible from all modules.
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    'Dim scalepy As Int : scalepy = 1
    'Dim IPBoxText As String : IPBoxText = ""
End Sub


Sub MB(title As String,msg As String,pos As String,can As String,neg As String) As Int
    Dim gBD As BetterDialogs
    Dim dlg_params As BD_CustomDlgParams
    Dim DR As Int
    Dim port As Boolean
    Dim lval As LayoutValues
    Dim sc As Float
    Dim Scrn As Double
    Dim psize, lsize As Int
    lval = GetDeviceLayoutValues
    sc = lval.scale
    Scrn = lval.ApproximateScreenSize
    If Scrn < 6 Then
'       psize = 18dip
'       lsize = 20dip
       psize = 18
       lsize = 20
      
    Else
'       psize = 35dip
'       lsize = 45dip
       psize = 35
       lsize = 45

    End If
   
    If Scrn > 7.5 Then
'       psize = 18dip
'       lsize = 20dip
       psize = 55
       lsize = 65
    End If      
   
   
    ' sc = 1
    If lval.Height > lval.Width Then
       port = True
    Else
       port = False
    End If
   
   
    Dim btnOK As Button
    btnOK.Initialize("")
    btnOK.Text = pos
    btnOK.TextColor = Colors.White

    'btnOK.Gravity = Gravity.CENTER ' + Gravity.CENTER_HORIZONTAL
   
    If port = True Then
      btnOK.TextSize = psize / sc '/sc
    Else
      btnOK.TextSize = lsize / sc '/sc
    End If   
    btnOK.Background = CreateStateListDrawable1

    'ToastMessageShow(" Port: "&port&" Height: "&lval.Height&" Width: "&lval.Width&"  SCALE: "&sc ,True)
   
    Dim btnCancel As Button
    btnCancel.Initialize("")
    btnCancel.Text = can
    If port = True Then
      btnCancel.TextSize = psize / sc '/ sc
    Else
      btnCancel.TextSize = lsize / sc '/sc
    End If   
    btnCancel.TextColor = Colors.White
    btnCancel.Background = CreateStateListDrawable1

    Dim btnneg As Button
    btnneg.Initialize("")
    btnneg.Text = neg
    If port = True Then
      btnneg.TextSize = psize / sc '/ sc
    Else
      btnneg.TextSize = lsize / sc '/sc
    End If   
    btnneg.TextColor = Colors.White
    btnneg.Background = CreateStateListDrawable1


    Dim pnlBody As Panel
    pnlBody.Initialize("")
    'pnlBody.LoadLayout("msgbody")

'    Dim pnlBody As Panel
'    pnlBody.Initialize("")
    Dim sld As StateListDrawable
    sld.Initialize
    Dim gd1 As GradientDrawable
    gd1.Initialize( "TOP_BOTTOM", Array As Int(Colors.DarkGray, Colors.Black))
    gd1.CornerRadius = 0dip
    sld.AddCatchAllState(gd1)
   
    Dim lab As Label


    lab.Initialize("")
    lab.Text = msg
'lab.Text = "Are You Sure You Want To End Your Shift Today. Maybe it will be tomorrow? It could even be the day after that - Who Knows?"   
    lab.TextColor = Colors.Yellow
    lab.Gravity = Gravity.CENTER_HORIZONTAL+Gravity.CENTER_VERTICAL
'    lab.Top = pnlBody.Top + 10dip
'    lab.left = pnlBody.left + 10dip
'    lab.width = 90%x
'    lab.Height = 90%y]

dlg_params.Initialize
dlg_params.Title = title
dlg_params.TitleWidth = -1
dlg_params.TitleHeight = 60dip
dlg_params.DialogBody = pnlBody
dlg_params.BodyWidth = 90%x
dlg_params.BodyHeight = 40%y
dlg_params.MarginHeight = 0dip
dlg_params.Background = sld
dlg_params.PositiveButton = btnOK
dlg_params.CancelButton = btnCancel
dlg_params.NegativeButton = btnneg
dlg_params.OpenKeyboard = False



' DR = gBD.CustomDialog( title,  -1,     60dip,    pnlBody,           90%x,     40%y, 0dip,   sld , btnOK, btnCancel, btnneg,  False,  "CD2"   )
'                       title, t_width, t_height,  Dialog -pnlbody, d_width, d_height, margin, background, btnok,btncancel,btnneg, openkeyboard, event)


    If port = True Then
       If Scrn < 6 Then
'         lab.TextSize = psize / sc
         pnlBody.AddView(lab, 10%x ,0%y , 70%x, 41%y)
'         pnlBody.AddView(lab, 10%x ,0%y , 70%x, 91%y)
        
         lab.TextSize = SetTextSize(lab,lab.Text,sc)
         DR = gBD.CustomDialog( dlg_params, "CD2"   )
       Else
'         lab.TextSize = psize / sc
         pnlBody.AddView(lab, 10%x ,0%y , 70%x, 41%y)
         lab.TextSize = SetTextSize(lab,lab.Text,sc)
         dlg_params.Title = "<H1>"&title&"</H1>"

         DR = gBD.CustomDialog(dlg_params, "CD2")
      
       End If
    Else

        pnlBody.AddView(lab , 5%x, 0 ,  80%x, 55%y)
        lab.TextSize = SetTextSize(lab ,lab.Text, sc)
         dlg_params.Title = "<H1>"&title&"</H1>"
         dlg_params.BodyWidth = 90%x
         dlg_params.BodyHeight = 60%y
         dlg_params.DialogBody = pnlBody

         DR = gBD.CustomDialog(dlg_params,  "CD2")
    '     DR = gBD.MsgBox(title,msg,btnOK.Text,btnCancel.Text,btnneg.Text,Null)
        

'        DR = gBD.CustomDialog( "<H1>"&title&"</H1>",  -1, 60dip,  pnlBody,  80%x, 60%y, 0dip,  sld , btnOK, btnCancel, btnneg, False, "CD2")
    End If
   
    'pnlBody.Color = Colors.Green
   
'    scalepy = scalepy + 1
'    If scalepy > 5 Then
'       scalepy = 1
'    End If
   
'    Log("DR=" & DR)
    Return DR
   
  
End Sub

Sub SetTextSize(lbl As Label, txt As String, Sca As Float) As Int
   Dim dt As Float
   Dim limit = 0.5 As Float
   Dim h As Int
   Dim stu As StringUtils
  
   lbl.Text = txt
   lbl.TextSize = 272
   dt = lbl.TextSize
   h = stu.MeasureMultilineTextHeight(lbl, txt)  
'   Log("Multi Line Height: "&h)
  
   Do While dt > limit Or h > lbl.Height
     dt = dt / 2
     h = stu.MeasureMultilineTextHeight(lbl, txt)  
     If h > lbl.Height Then
       lbl.TextSize = lbl.TextSize - dt
     Else
       lbl.TextSize = lbl.TextSize + dt
     End If
   Loop
   If Sca = 99.0 Then
      Return lbl.TextSize' / 1.30 '(scale / 2) ' 1.35
  
   Else
       Return lbl.TextSize / 1.20 '(scale / 2) ' 1.35

   End If
  
      
End Sub

Sub CD2_BackKeyPressed As Boolean
    Log("Back key detected")
    Return True 'Prevents the cancellation of the dialog
End Sub

Sub CreateStateListDrawable1 As StateListDrawable
    'Creates a SLD for the buttons of the custom dialog
    Dim sd As StateListDrawable
    sd.Initialize
    Dim gd1 As GradientDrawable
    gd1.Initialize("BOTTOM_TOP" , Array As Int(Colors.Gray, Colors.DarkGray))
    gd1.CornerRadius = 0dip
   
    Dim gd2 As GradientDrawable
    gd2.Initialize( "BOTTOM_TOP", Array As Int(Colors.DarkGray, Colors.Gray))

    gd2.CornerRadius = 0dip
    sd.AddState(sd.State_Pressed, gd2)

    sd.AddCatchAllState(gd1)

    Return sd
End Sub


Sub CreateStateListDrawable As StateListDrawable
    'Creates a SLD for the buttons of the custom dialog
    Dim sd As StateListDrawable
    sd.Initialize
    Dim gd1 As GradientDrawable
    gd1.Initialize("BOTTOM_TOP" , Array As Int(Colors.Gray, Colors.DarkGray))
    gd1.CornerRadius = 10dip
   
    Dim gd2 As GradientDrawable
    gd2.Initialize( "BOTTOM_TOP", Array As Int(Colors.DarkGray, Colors.Gray))

    gd2.CornerRadius = 10dip
    sd.AddState(sd.State_Pressed, gd2)

    sd.AddCatchAllState(gd1)

    Return sd
End Sub

Sub LoadDrawable(Name As String) As Object
    'Gets a drawable from the Android system resources
    Dim r As Reflector
    r.Target = r.GetContext
    r.Target = r.RunMethod("getResources")
    r.Target = r.RunMethod("getSystem")
    Dim ID_Drawable As Int
    ID_Drawable = r.RunMethod4("getIdentifier", Array As Object(Name, "drawable", "android"), _
                                                Array As String("java.lang.String", "java.lang.String", "java.lang.String"))
    r.Target = r.GetContext
    r.Target = r.RunMethod("getResources")
    Return r.RunMethod2("getDrawable", ID_Drawable, "java.lang.int")
End Sub
 

Harris

Expert
Licensed User
Longtime User
Solved... Forgot to add following in manifest (again...). Someday I will remember these things...
Actually, my friend reminded me that I had this issue 1 year ago - and how I resolved it.
Must be nice to have a long term memory!

SetApplicationAttribute(android:theme, "@android:style/Theme.Holo")
 

welu1805

Active Member
Licensed User
Longtime User
Hi all,

I want to use a CustomDialog with some edittext fields and one button. The button should open a filedialog to search an image.

B4X:
Sub btnFileDialog_Click
    Log("in btnFileDialog_Click")
    Dim fd As FileDialog
    fd.Show("Select file", "Yes", "No", "", Null)
End Sub

The Log works, but fd.Show doesn't work.

What is wrong?

Lutz
 
Top