B4A Class DOTips 2.7 - show an overlay for app tips

Class Module: DOTips
Author: Dave O'Brien
Code Version: 2.7
Last Mod: 29 Nov 2022

Changes in this version:

- Fixed crash on showing tips for views on certain versions of Android (e.g. Android 11 Go Edition)


DOTips is a free B4A class for showing "spotlight" tips in your app.

These are commonly used for tutorials, onboarding, or showing users what's new. The tips are overlaid on your UI using a semi-transparent background, and can highlight a UI control or an arbitrary area, show a picture, or just show text.

To use, first add this class and its required libraries:
- Add this class module to your B4A project using "Add Existing Modules".
- In the Libraries Manager, make sure these internal (and free) libraries are ticked:
- JavaObject​
- StringUtils​
- Accessibility

Create a variable for the tips:
- In the activity's Sub Globals, add Dim tips As DOTips
- In the activity's Activity_Create, add tips.Initialize(Me, Activity, "tips")

To show tips, add them to the tips list and call Show:

B4X:
tips.addGeneralTip("Insert title here", "Insert description here")
tips.addPictureTip("picture.png", "Insert description here")
tips.addTipForView(someView, "Insert title here", "Insert description here")
tips.addTipForArea(someRect, someScrollview, "Insert title here", "Insert description here")
tips.show
This will show the tips in order, using the default color, text, and automatic positioning (which adjusts to the location of the view).

Note: If a view is not visible when Show is called, that tip is skipped.

To customize tips:
- Set the properties you want first. All tips you add after that will use those settings.
B4X:
tips.HighlightColor = Colors.Magenta
tips.LandscapePosition = tips.POSITION_LEFT
tips.addTipForView(someView, "Insert title here", "Insert description here")

To hide the tips when the device's Back button is tapped, add this:
B4X:
Sub activity_KeyPress(KeyCode As Int) As Boolean
   If (tips.Visible = True) And (tips.CanSkip) Then
      tips.hide(True)
      Return True
   else...

To trigger something after the tips are closed, use the OnHide event:
B4X:
sub tips_OnHide(tipsSkipped As Int)
   'do something here if desired
end sub

To resume tips after orientation changes, use GetIndexOfCurrentTip and Resume.
In the demo code, see the activity_pause and activity_resume subs.

To hide the Skip All button, set canSkip to false.

For help on the properties and methods, use the automatic tooltips in B4A or inspect the source code.

Demo code
I've attached a demo app that lets you play with all of the properties and see the tips in action.

Compatibility:
Works with B4A 4.3+. Not sure about earlier versions.
Tested on Android 4.x and later, on various phones and tablets.

Not yet implemented:
- auto-size buttons to text
- add animated transitions between tips
- change string parameters to CSBuilder
- make this a customView?

Usage:
- Creative Commons Attribution license
(You can do whatever you like with this, as long as you credit me as the creator.)

Thanks to:
- @Erel for the GetARGB code (and lots more besides)
- @klaus for the drawRoundRect code
- @thedesolatesoul for porting MSShowTips, which wasn't quite what I needed, but motivated me to give it a go myself. :)
- @stevel05 for the GetRelativeLeft and GetRelativeTop code

Questions, suggestions, bugs? Please post in this thread.

Thanks!

sample tip 2.png
sample tip 3.png
sample tip 1.png
 

Attachments

  • DOTips.bas
    55.5 KB · Views: 143
  • DOTips-demo.zip
    289.1 KB · Views: 147
Last edited:

somed3v3loper

Well-Known Member
Licensed User
Longtime User
Here is a screenshot


nb8jB5T.jpg


And a quick question : Is visible false after hiding the tip ?

I could not use this to show the tip every time lbl gets clicked :


B4X:
Sub lbl_Click
    If tipz.Visible=False Then
        tipz.show

    End If

End Sub

I get the tip only first time .
 

b4auser1

Well-Known Member
Licensed User
Longtime User
Hi, Dave

I see in the attached files only DoTips.bas

Please attach demo app. Thank you.
 

Dave O

Well-Known Member
Licensed User
Longtime User
@b4auser1 : Not sure why those other files didn't appear, but I've uploaded them again. Let me know if you have any questions or comments.
 

Dave O

Well-Known Member
Licensed User
Longtime User
Here is a screenshot

> And a quick question : Is visible false after hiding the tip ?
Visible is only really used if you're capturing the Back button during Activity_KeyPress. If the tips are visible when the user presses the Back hard button, you can capture this and hide the tips.

Tips are typically shown when you open a screen for the first time (for example, when the app is first installed and run, and you want to give the user a tour of the app), or when a new version is released (and you want to point out a new button you've added, for example).

It's not really meant to be "help" for a control on demand, although I suppose you could do that by adding a help icon beside a control, which would add the tip and show it.
 
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
How can help icon be different ?

Which help icon do you mean?

Also, in the screenshot you uploaded, if you want to show a tip for the label, the label should be highlighted, not the app icon. Could you post the code you wrote?
 

Dave O

Well-Known Member
Licensed User
Longtime User
long waited one, thank you so much for this
No worries, glad to give something back to the community that has been so generous to me. :)

Let me know if you think of a way to improve this class. Cheers!
 

jotaele

Member
Licensed User
Longtime User
When the view is a Button, I get the following error:

java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams

With other views that I tried works well.

EDIT: Sorry, I see that:

Not yet implemented:
- auto-size buttons to text
 
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
@jotaele, buttons should work just like other views. The demo app includes two tips about buttons.

Can you post a code snippet so we can figure out the problem?

BTW, the "auto-size buttons to text" item is about allowing buttons with longer text (e.g. for languages like German that need more space). Currently the buttons are a fixed width, but ideally they should auto-size to the text they contain.

When the view is a Button, I get the following error:

java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams

With other views that I tried works well.

EDIT: Sorry, I see that:

Not yet implemented:
- auto-size buttons to text
 

Dave O

Well-Known Member
Licensed User
Longtime User
I've just uploaded version 1.1.

The only change is that DOTips no longer requires the ABExtDrawing library.
 

jotaele

Member
Licensed User
Longtime User
@jotaele, buttons should work just like other views. The demo app includes two tips about buttons.

Can you post a code snippet so we can figure out the problem?

BTW, the "auto-size buttons to text" item is about allowing buttons with longer text (e.g. for languages like German that need more space). Currently the buttons are a fixed width, but ideally they should auto-size to the text they contain.

(Sorry for my bad English)

Ok. I'm sorry, but I misunderstood.

In fact, in your example, the buttons are working. I follow the code, but in my app, the layout of the button is not avalaible. I tried with another button and works well. I found then the another button that have the error, use a VT (View Tagger). For any reason, If I apply the VT class to a button, the layout is not avalaible when your class try to access it.

Its not a problem. I will use addTipForArea method.

By the way, If you want, I can add three parameters more to the class.

The width of the stroke, the radius of the corner, spacer and outlinePadding. This would be awesome, and its easy to do.

I can modify the class, but it will be perfect if the user can do it with methods and properties.

B4X:
Private spacer As Int = 30dip
Private outlinePadding As Int = 5dip

drawRoundRect(tempCanvas, tempRect, 20dip, tip.highlightColor, Colors.Transparent, 10dip)

Thanks,
 
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
Hi @jotaele, thanks for the suggestions. I agree that it's better to make all those item configurable, so I've added the following properties to version 1.2:
  • highlightRadius
  • highlightWidth
  • highlightPadding
  • spacer
Give it a try and let me know if I missed or mangled anything. :)
 

jotaele

Member
Licensed User
Longtime User
(Sorry for my bad English)

Ok. I'm sorry, but I misunderstood.

In fact, in your example, the buttons are working. I follow the code, but in my app, the layout of the button is not avalaible. I am debugging now to find the "bug".

By the way, If you want, I can add three parameters more to the class.

The width of the stroke, the radius of the corner, and outline spacer. This would be awesome, and its easy to do.

We can modify the class, but it will be perfect if the user can do it with methods and properties.

Thanks, I will report if I find the error of my code.
Hi @jotaele, thanks for the suggestions. I agree that it's better to make all those item configurable, so I've added the following properties to version 1.2:
  • highlightRadius
  • highlightWidth
  • highlightPadding
  • spacer
Give it a try and let me know if I missed or mangled anything. :)


Awesome!!!!

I tried all options and works well. Later, when I have time, I will make you another suggestions, if you want, but I must test in depht your class.

Thanks a lot by your excelent work.
 

Dave O

Well-Known Member
Licensed User
Longtime User
I've uploaded version 1.3, with these changes:
- New method addGeneralTip lets you show tips that don't highlight a particular view or area.
- Minor code clean-up.
 

jotaele

Member
Licensed User
Longtime User
Awesome!!!!

I tried all options and works well. Later, when I have time, I will make you another suggestions, if you want, but I must test in depht your class.

Thanks a lot by your excelent work.

@Dave O

All its fantastic. You make easy put the tutorials in my app.

I will dare to discuss a couple of things, without intention of ofense.

I want to touch the alpha, because if the text is over the highlited, its very confusing. But I tried the method:

'Tips.combineColorAndAlpha(Colors.black, 10)

But not show any changes. I tried with another colors, and I am thinking that is not the method to use.

Other thing, is the color of the buttons and the bold option for title and coment. Its only an apreciation. I am very happy with your lib.
 

Dave O

Well-Known Member
Licensed User
Longtime User
Hi @jotaele, agreed, I will add a public property for the alpha of the "mask" that holds the title and description.

In the meantime, you can change this using Tips.combineColorAndAlpha(Colors.black, NN), where NN is the alpha of the mask itself, which combines with the alpha of the entire tipsPanel. So NN is how much "darker" you want the mask to be. I think the current value is 90, but you may want to increase it for your needs.

The button color is another good one to make public, and probably the button text color too (because they interact with each other).

Thanks for the helpful feedback!
 
Top