Android Question The Sleep (0) problem for the custom date picker class

yshzsl

Member
I am developing a date picker class,It has been basically completed,Function is similar to the DatePicker of B4J.The running interface is as follows:
DatePicker.jpg


In the class, I used the layout file,It works fine in the Button_Click code.However, you must run Sleep (0) in the B4XPage_Created code before you can work properly.
Like the following code:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Sleep(0)
    zDatePicker1.Language="chinese"
    zDatePicker1.Width=130dip
    zDatePicker1.Height=25dip
    zDatePicker1.PickerPanelWidth=200dip
    zDatePicker1.PickerPanelHeight=200dip
    zDatePicker1.TextSize=14
    zDatePicker1.Text="09/06/2024"
End Sub
I don't know where the problem is, please help me.Thanks!

Note: B4A.DependsOn=DateUtils,SQL,StringUtils,ScrollView2D,Table
 

Attachments

  • zDatePicker.zip
    11.8 KB · Views: 37
  • Library.zip
    61.9 KB · Views: 34
Last edited:
Solution
Thanks for your attention, Erel
I think the problem is with Base_Resize。
The problem is not related to Base_Resize. it's because you used UI objects before the UI loading was completed. even if you did this:
B4X:
 zDatePicker1.Language="chinese"

As Erel said:
It is currently not possible to load a layout while another one is being loaded. you need to keep the Sleep(0) call in DesignerCreateView and in your main code.
Running Sleep (0) is to wait for the UI to be refreshed.
If you would not like to use sleep(0) in main, you can change InitClass to public sub, and then replace sleep(0) with zDatePicker1.InitClass
such as
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")...

yshzsl

Member
hello,Erel.
If I delete Sleep (0),Even using Sleep (0) in B4XPage_Created,It causes the following error too:
B4X:
** Activity (main) Create (first time) **
Error occurred on line: 167 (zDatePicker)
java.lang.RuntimeException: java.lang.ClassCastException: b4a.example.zdatepicker cannot be cast to android.widget.TextView
    at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:155)
    at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:134)
    at anywheresoftware.b4a.objects.B4XViewWrapper.LoadLayout(B4XViewWrapper.java:329)
    at b4a.example.zdatepicker._initclass(zdatepicker.java:234)
    at b4a.example.zdatepicker._designercreateview(zdatepicker.java:986)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:61)
    at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:147)
    at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:134)
 
Upvote 0

yshzsl

Member
I didn't see that you are calling LoadLayout from InitClass. It is currently not possible to load a layout while another one is being loaded. You need to keep the Sleep(0) call in DesignerCreateView and in your main code.
Thanks for your attention, Erel

I think the problem is with Base_Resize。
In the booklet,Custom views has no Base_Resize program stream in B4A,So I called Base_Resize in the code in InitClass,But Base_Resize ran before I call,It still runs after deleting the Base_Resize call.
I have created a new Panel1_Resize subroutine,I copy the code from Base_Resize to Panel1_Resize and remove the Base_Resize code,But Panel1_Resize still runs automatically before loading the layout, It Still unable to find the Panel1.
Code is as follows:
B4X:
Private Sub Base_Resize (Width As Double, Height As Double)
    mWidth=Width
    mHeight=Height   
End Sub

Private Sub Panel1_Resize (Width As Double, Height As Double)
    Log("bbb")
    mWidth=Width
    mHeight=Height
   [B] Panel1.Width=mWidth[/B]
    Panel1.Height=mHeight
    Dim size As Int=mHeight
    Panel3.Top=0
    Panel3.Height=size
    Panel3.Width=size
    Panel3.Left=mBase.Width-size
    Dim size1 As Int=mHeight*2/3
    ImageView1.Height=size1
    ImageView1.Width=size1
    ImageView1.Top=(mHeight-size1)/2
    ImageView1.Left=(size-size1)/2   
    Dim lwidth As Double=mBase.Width-Label1.Left-size
    Label1.Width=lwidth
    Label1.Height=mHeight
End Sub

Private Sub InitClass
    mBase.RemoveAllViews   
    mBase.LoadLayout("View")
    TouchPanel.RemoveView
    mParent.AddView(TouchPanel,0,0,mParent.Width,mParent.Height)
    mBase.As(Panel).Elevation=10dip
    Log("aaa")
    Panel1_Resize(mWidth,mHeight)
    Label1.Typeface=mFont
    Label1.Text=mText
    Label1.TextColor=IIf(mEnabled=False,Colors.LightGray,mTextColor)
    Label1.TextSize=mTextSize
    Alignment=gmap.GetDefault(mAlignment,Array As String("CENTER","LEFT"))
    Label1.As(B4XView).SetTextAlignment(Alignment(0),Alignment(1))
    Panel1.Color=mBackgroundColor
    Panel1.As(B4XView).SetColorAndBorder(mBackgroundColor,mBorderSize,mBorderColor,mBorderRadius)
    cvsBase.Initialize(mBase)
    rectBase.Initialize(0, 0, mBase.Width, mBase.Height)
    DateView_Initialize   
End Sub

Panel1.Width=mWidth
The error appears in this sentence.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Thanks for your attention, Erel
I think the problem is with Base_Resize。
The problem is not related to Base_Resize. it's because you used UI objects before the UI loading was completed. even if you did this:
B4X:
 zDatePicker1.Language="chinese"

As Erel said:
It is currently not possible to load a layout while another one is being loaded. you need to keep the Sleep(0) call in DesignerCreateView and in your main code.
Running Sleep (0) is to wait for the UI to be refreshed.
If you would not like to use sleep(0) in main, you can change InitClass to public sub, and then replace sleep(0) with zDatePicker1.InitClass
such as
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")  
    zDatePicker1.InitClass    'Sleep(0)
    zDatePicker1.Language="chinese"
    zDatePicker1.Width=130dip
    zDatePicker1.Height=25dip
    zDatePicker1.PickerPanelWidth=200dip
    zDatePicker1.PickerPanelHeight=200dip
    zDatePicker1.TextSize=14
    zDatePicker1.Text="09/06/2024"
End Sub
 
Upvote 0
Solution

yshzsl

Member
Thanks for the advice, teddybear.

Your advice has reminded me ,I tested the process of loading the UI again, I found that Base_Resize was called three times during the loading UI,It is called by three routines, setWidth, setHeight and InitClass,setWidth and setHeight will call Base_Resize before InitClass,But the layout file is loaded in the InitClass,So setWidth and setHeight can not find the Panel1.
After changing the setWidth and setHeight routines to call InitClass,Everything is normal.Sleep (0) or zDatePicker1.InitClass is not required in B4XPage_Created.

Thank you again,Erel,teddybear!
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I had a look at your problem, because i remember having had similar problems and i would have liked to help.
I downloaded your zip file, and surprise just the .bas file, but unfortunately not even a small project showing the problem for testing.
Well, I defined a new project and added your zDatePicker.bas class and ran the project.
Oh surprise, a lot of red lines showing errors.
Table, what is table ?
Then I remembered the Table class in FelxibleTable.
I added it, added other needed libraries and get an error no view.bal file.
I like to help, but sorry, i must say that it is very disappointing to help people giving not enough information.

Then, using the Table class, about 5000 lines of code, just foshowing the dates for a date picker looks to me as none sense, because this class is a 'monster' just to display some dates, all this could be done with much less code lines and more specific, well this is only my opinion !?
And without the view,bas file i cannot test anything to see what yo do and how and what your problem is.
Really, SORRY !
 
Upvote 0

yshzsl

Member
Thanks for the guidance, klaus.
The View.bal is In the zDatePicker.zip compressed file, Maybe you didn't notice it.

I feel the same way, It's indeed a bit overqualified for petty use that the Table class is used for the zDatePicker class.
In the project that I was developing, Date selectors will be used frequently,But I can not seems to find DatePicker similar to B4J in B4A. I decided to develop a similar custom view class by himself while learning. Since I am familiar with the Table class, I can achieve my goals with less code, So I used the Table class. But there's a downside that it's running a bit slow.
I want to create a similar class using code instead of layout files, and I am considering what elements are using in the date selection table,I hope you can give me a good idea.

Thanks again for helping me as a novice!!
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Some questions:
- Is your project supposed to be a B4XPages project ?
The project you posted in post #1 is not a B4XPages project, therefore we cannot test it in the same conditions as you do.

- How did you zip the project ?
For a B4A only project you should use Export As Zip in the File menu:
1725887518792.png

For a B4XPages project you should press the Ctrl key and click on this line on top in the B4XMainPahe module.
1725887697660.png

- Do you want the DatePicker only for B4A, or multi-platform ?

- Currently, when you click on the calendar without a date the program you get an error because there the table returns an empty string .

This is how it looks like on my phone !?

1725889207073.png


Unfortunately, it would need quite some time trying to study your code.
Anyway, for the calendar, I would make it with a Canvas and drawing the dates.
 
Upvote 0

yshzsl

Member
Hello,klaus.
Thank you for your attention and help!You gave me very good advice.
I am now creating this class using the code instead of the layout file,The date panel uses Label instead of Table,It has now been basically completed,I am testing it.
Using Canvas may be a better option,But I have never used it before.I will be traveling for a week tomorrow,I will learn and use it to create this class while Coming back.
Thank you for the guidance.
 
Upvote 0

yshzsl

Member
The first draft of this class created with code instead of layout files has been completed,It took half a day to test,No problem has been found yet.

Library files and example files are uploaded,Research testing are welcome.
 

Attachments

  • zDatePicker.b4xlib
    10.2 KB · Views: 28
  • Project.zip
    24.8 KB · Views: 30
  • DependsOn.txt
    48 bytes · Views: 26
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
Looks very nice.
But unfortunately it works only with B4A.
Why did you not make directly a cross-platform customview, this might interest more users.

I would suggest you to use in the future as much as possible B4XViews instead of platform specific views even if your project is intended for only one platform.
B4XViews have some more properties which are not available for the equivalent platform specific views.
A good example is the Color property, this one is write only in B4A, with a B4XView it is also writable.
 
Upvote 0

yshzsl

Member
Hello,klaus.

I traveled for a few days,I failed to respond to your advice,so sorry!

Using B4xview to develop cross-platform classes is a good choice,Thank you for your suggestions.
I will work hard about cross-platform development,And transform this class into a cross-platform class.
 
Upvote 0

yshzsl

Member
I have tried to develop cross-platform libraries,This zDatePicker class can be used for both B4A and B4J Currently .
Since there is no ios device,I have not studied the B4I,So no B4I code was developed.

Always feels like the cross-platform code is a little messy,It is not as clear as the code for a single platform,I wonder if there is something wrong with my method.
 

Attachments

  • Project.zip
    29.2 KB · Views: 24
Upvote 0

klaus

Expert
Licensed User
Longtime User
Always feels like the cross-platform code is a little messy ...
You are not using enough xui and B4XViews.
It will simplify your code quite a bit.
You should use those as much as possible, even for single platform applications.

To get colors, no need to have specific code for B4A, just use the code below, valid for all three platforms:
B4X:
    mBodyBackground=xui.PaintOrColorToColor(Props.Get("BodyBackground"))

For colors use always xui colors
B4X:
xui.Color_LightGray
no deed to have specific B4A code like:
B4X:
Colors.LightGray

For text alignment you should use:
B4X:
    MonthLabel.SetTextAlignment("CENTER", "CENTER")
No need for specific B4A Gravity code.

To set a bitmap to an ImgeView, set it as a B4XView and use the code below, it is cross-platform:
B4X:
ImgeView,SetBitmap(bmp)
 
Upvote 0

yshzsl

Member
Hello,klaus.

Thank you for the time and energy in giving me guidance,I seem to understand,The XUI and the B4XVIEW are cross-platform,When developing cross-platform classes or other APP,The XUI and B4XVIEW shall be as used as possible,Use specific views or code as little as possible.

By developing this class, I have learned a lot,Especially under your careful guidance, I feel a very fast progress.

Thanks again for your guidance,I will change the code once again following your guidance.
 
Upvote 0

yshzsl

Member
Following the guidance of Mr.klaus., I revised the code.
The code is a lot smaller and more organized.
Thanks again to Mr.klaus.
 

Attachments

  • Project.zip
    29.2 KB · Views: 22
Upvote 0
Top