Android Question trapping clicks from a view created on the fly

67biscuits

Member
It seems a newby's problem, but I am hoping that someone can shove me in the right direction. I have figured out how to make a three spinner object and placed it successfully in a panel. The objects are spinners from which the date segments are selected. How do I catch the click/selection from the said spinners?
Also, wondering how can economize the code a little further with the "filler" list. I can't seem to make it work thus its rem'd out. Any suggestions? It probably has something to do with lists vs arrays, which keep tripping me up, albeit less so now that before.

cheers all
Charley

Sub Create_grid(p As Panel, r As Int, c As Int) Dim days() As Int = Array As Int(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31) Dim months() As String = Array As String("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec") Dim years() As Int = Array As Int( DateTime.GetYear(DateTime.Now), DateTime.GetYear(DateTime.Now) + 1, DateTime.GetYear(DateTime.Now) + 2) 'Dim filler As List = Array As List (days,months,years) 'either lists or direct data make no diff Dim s As Spinner For row = 0 To r-1 For col = 0 To c - 1 s.Initialize("s") p.AddView(s, p.Width / 3 * col, 0, p.Width / 3, 100) 's.AddAll(filler.get(col)) 'it yacks here If col = 0 Then s.AddAll(days) If col = 1 Then s.addall(months) If col = 2 Then s.AddAll(years) 'how to set primary selection to current date Next Next 's.initialize("s") 'p.AddView(s, 0, 0, p.Width / 3, p.Width / 3) 's.AddAll(days) 's.selectedindex = DateTime.GetDayOfMonth(DateTime.now) ' 's.initialize("s") 'p.AddView(s, p.Width / 3, 0, p.Width / 3, p.Width / 3) 's.AddAll(months) 's.SelectedIndex = DateTime.GetMonth(DateTime.Now) ' 's.Initialize("s") 'p.AddView(s, (p.Width / 3)* 2, 0, p.Width / 3, p.Width / 3) 's.AddAll(years) 's.SelectedIndex = DateTime.GetDayOfYear(DateTime.Now) ' End Sub:
Sub Create_grid(p As Panel, r As Int, c As Int)

    Dim days() As Int = Array As Int(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31)
    Dim months() As String = Array As String("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec")
    Dim years() As Int = Array As Int( DateTime.GetYear(DateTime.Now), DateTime.GetYear(DateTime.Now) + 1, DateTime.GetYear(DateTime.Now) + 2)
    
'    Dim filler As List = Array As List (days,months,years) 'either lists or direct data make no diff
            
    Dim s As Spinner
    For row = 0 To r-1
        For col = 0 To c - 1
            s.Initialize("s")
            p.AddView(s, p.Width / 3 * col, 0, p.Width / 3, 100)

'            s.AddAll(filler.get(col))  'it yacks here

            If col = 0 Then s.AddAll(days)
            If col = 1 Then s.addall(months)
            If col = 2 Then s.AddAll(years)
            
            'how to set primary selection to current date
        Next
    Next

'    s.initialize("s")
'    p.AddView(s, 0, 0, p.Width / 3, p.Width / 3)
'    s.AddAll(days)
'    s.selectedindex = DateTime.GetDayOfMonth(DateTime.now)
'       
'    s.initialize("s")
'    p.AddView(s, p.Width / 3, 0, p.Width / 3, p.Width / 3)
'    s.AddAll(months)
'    s.SelectedIndex = DateTime.GetMonth(DateTime.Now)
'   
'    s.Initialize("s")
'    p.AddView(s, (p.Width / 3)* 2, 0, p.Width / 3, p.Width / 3)
'    s.AddAll(years)
'    s.SelectedIndex = DateTime.GetDayOfYear(DateTime.Now)
'       
End Sub
 

Brian Dean

Well-Known Member
Licensed User
Longtime User
Have a look at this code. I have not used spinners before so there might be a better way, but this works for me.
B4X:
Sub setup
    Dim months() As String = Array As String("Jan", "Feb", "Mar", "Apr", "May", _
          "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec")
    Dim now As Long = DateTime.now            ' Current date and time
    For i = 1 To 31
        spnDay.Add(i)                       ' Add days and set to current
    Next
    spnDay.SelectedIndex = DateTime.GetDayOfMonth(now) - 1
    spnMonth.AddAll(months)                  ' Add months and set to current
    spnMonth.SelectedIndex = DateTime.GetMonth(now) - 1
    Dim thisYear As Int = DateTime.GetYear(now)
    spnYear.Add(thisYear)                       ' Add current and imminent years
    spnYear.Add(thisYear + 1)
    spnYear.Add(thisYear + 2)
    spnDate_ItemClick(0, 0)                   ' Dummy call to initialise label text
End Sub

Sub spnDate_ItemClick (Position As Int, Value As Object)
    lblDate.Text = spnDay.SelectedItem & " " & spnMonth.SelectedItem & " " & spnYear.SelectedItem
End Sub

I attach the complete project. Look at the script in the layout file - this sets up the spinners to evenly occupy the panel width. The three spinners all use the same event which simplifies the code a lot.
 

Attachments

  • Spinners.zip
    9.7 KB · Views: 8
Last edited:
Upvote 0

67biscuits

Member
ll am
I'm not sure that I understand what you are doing, however you set the spinner "event name" to "s". This means that you can catch the event with:
B4X:
Private Sub s_ItemClick (Position As Int, Value As Object)
    Dim sp As Spinner = Sender
End Sub
Yes, that makes sense. thanks Erol.
I am experimenting with dynamic controls by fabricating a date picker.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Better approach - create a custom view.

 
Upvote 0

67biscuits

Member
Have a look at this code. I have not used spinners before so there might be a better way, but this works for me.
B4X:
Sub setup
    Dim months() As String = Array As String("Jan", "Feb", "Mar", "Apr", "May", _
          "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec")
    Dim now As Long = DateTime.now            ' Current date and time
    For i = 1 To 31
        spnDay.Add(i)                       ' Add days and set to current
    Next
    spnDay.SelectedIndex = DateTime.GetDayOfMonth(now) - 1
    spnMonth.AddAll(months)                  ' Add months and set to current
    spnMonth.SelectedIndex = DateTime.GetMonth(now) - 1
    Dim thisYear As Int = DateTime.GetYear(now)
    spnYear.Add(thisYear)                       ' Add current and imminent years
    spnYear.Add(thisYear + 1)
    spnYear.Add(thisYear + 2)
    spnDate_ItemClick(0, 0)                   ' Dummy call to initialise label text
End Sub

Sub spnDate_ItemClick (Position As Int, Value As Object)
    lblDate.Text = spnDay.SelectedItem & " " & spnMonth.SelectedItem & " " & spnYear.SelectedItem
End Sub

I attach the complete project. Look at the script in the layout file - this sets up the spinners to evenly occupy the panel width. The three spinners all use the same event which simplifies the code a lot.
Thanks Brian. I originally tried the non iteration method, but thought it might be good to understand the logistics, in case this project got big. I like the way did that. Your example is not a repeatable dynamic code though is it? I would have three or four different 'panels' to propagate at various times. Ultimately it may be a project manager, so dates time will be a critical part popping up all over the show.
(I'm converting an app written in AI2/blockly)
Is your method repeatable?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
. I originally tried the non iteration method, but thought it might be good to understand the logistics

You are right. You need to know what you are doing.

Some tips:
s.SelectedIndex = DateTime.GetDayOfYear(DateTime.Now)
GetDayOfYear returns an INT of 1 to 366. This is not what you need

s.selectedindex = DateTime.GetDayOfMonth(DateTime.now)
GetdayofMonth return an STRING. But you need an INT to set SelectedIndex. You need to find the day in your array to know the index
 
Upvote 0

67biscuits

Member
You are right. You need to know what you are doing.

Some tips:

GetDayOfYear returns an INT of 1 to 366. This is not what you need


GetdayofMonth return an STRING. But you need an INT to set SelectedIndex. You need to find the day in your array to know the index
I did at some point have your second example. I used the int to extract the month from the strings list. Retrieving that information is a more simple portion of the equation. (I just reread the original post; where it says GetDayOfYear is a Tab key typo. It's meant to be .GetYear) Thanks for that
 
Upvote 0

67biscuits

Member
note to all: Please know that I not a software engineer. I am carpenter who needs to learn the basics of B4A in order to build a foundation upon which to build programming skills. I studied it back in the 90's but programming now is a very different animal. I will teach you how to build a hut before you build a mansion, I need the same consideration.
I appreciate your patience, thanks
Charley
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
Your example is not a repeatable dynamic code though is it?
No - but it could be, although I am not sure what you mean by "dynamic" - it is a term that seems to mean different things at different times, which is itself "dynamic" I suppose. I have loaded the layout directly to the main form but I could have created a panel "dynamically" and then loaded the layout to that panel - a layout can be re-used.

I would have three or four different 'panels' to propagate at various times. Ultimately it may be a project manager, so dates time will be a critical part popping up all over the show.
That sounds to me like a description of a date-entry dialogue - there are many ready-made examples of those - but only you can know that. Don't worry about it - learning by trial and error is not a bad way to proceed, and there is usually more than one way to achieve a goal.
 
Last edited:
Upvote 0

67biscuits

Member
No - but it could be, although I am not sure what you mean by "dynamic" - it is a term that seems to mean different things at different times, which is itself "dynamic" I suppose. I have loaded the layout directly to the main form but I could have created a panel "dynamically" and then loaded the layout to that panel - a layout can be re-used.


That sounds to me like a description of a date-entry dialogue - there are many ready-made examples of those - but only you can know that. Don't worry about it - learning by trial and error is not a bad way to proceed, and there is usually more than one way to achieve a goal.
No - but it could be, although I am not sure what you mean by "dynamic" - it is a term that seems to mean different things at different times, which is itself "dynamic" I suppose. I have loaded the layout directly to the main form but I could have created a panel "dynamically" and then loaded the layout to that panel - a layout can be re-used.


That sounds to me like a description of a date-entry dialogue - there are many ready-made examples of those - but only you can know that. Don't worry about it - learning by trial and error is not a bad way to proceed, and there is usually more than one way to achieve a goal.
dynamic as in having the ability to drop the views in at run time. I suppose any code could be dynamic. I will potentially have 6 panels (which I am trying to figure a way of having, again, dynamic views, but each panel will be required to collect very different information. A problem for down the road. Right now I am just cutting my teeth on the basics and going up from there.
 
Upvote 0

67biscuits

Member
I am now using the AnotherDatePicker view. After a good 6 hours of typing endless code to decipher invariably thousands of keystrokes to capture a date and time in what turned out to be only 6 areas to catch a date/time combo, the page was half a mile long, compared to two lines with AnotherDatePicker.
Lesson learned, keep the options to a minimum, pick yer battles and KISS.

Is there a matching timepicker?
 
Upvote 0
Top