I am attempting to create a dynamically allocated panel situation which gets added into the customlistview, based on the number of connected UI classes.
It works fine if theres only one connected class/panel. The minute there are two or more, I get an IllegalStateException that the specified child already has a parent and a crash
I am probably making a mistake somewhere in the code, but I am declaring an ItemPanel each time so I am not sure why this is occuring.
pnlWidget are the parent panels for the class array, that gets initialized and setup early on during the Activity load. Those are all good.
Here is the code:
And, here is the error:
Any thoughts? Thanks
It works fine if theres only one connected class/panel. The minute there are two or more, I get an IllegalStateException that the specified child already has a parent and a crash
I am probably making a mistake somewhere in the code, but I am declaring an ItemPanel each time so I am not sure why this is occuring.
pnlWidget are the parent panels for the class array, that gets initialized and setup early on during the Activity load. Those are all good.
Here is the code:
B4X:
'Refresh widgets in the list views.
Sub UpdateWidgets
Log("Updatewidgets called")
'Enumerate through all widgets, accumulate the total of connected widgets for a specific scoreboard.
Dim NumWidgetsNeeded As Int = 0
Dim IndexMap As Map
'Accumulate the total number of connected scoreboard operators, store each connected parent panel in the hashtable
IndexMap.Initialize
For I = 0 To ScoreWidgets.Length-1
If ScoreWidgets(I).IsInitialized = True Then 'Make sure the particular widget was initialized to begin with before running our tests
If ScoreWidgets(I).IsConnected = True Then
IndexMap.Put(NumWidgetsNeeded, I) 'Store the parent panel index location in the given hashtable
Log(NumWidgetsNeeded & "," & I)
NumWidgetsNeeded = NumWidgetsNeeded + 1 'Accumulate to the total of connected widgets
End If
End If
Next
If NumWidgetsNeeded = 0 Then 'There are no active connections
clvRight.Clear
clvLeft.clear
Return
End If
'Add currently connected scoreboard widgets to the list view
'Lets determine the maximum number of widgets that can be shown in a listview.
Dim MaxWidgets As Int = Floor(clvLeft.AsView.Height / pnlWidget(0).Height) 'Maximum number of widgets the view can actually hold
If MaxWidgets < NumWidgetsNeeded Then 'If the number of widgets needed exceed that of the views capability, we have to span views
'Make sure both listviews are visible and aligned properly.
clvLeft.Clear
clvRight.Clear
clvLeft.AsView.Left = InitialLeftPosition
clvRight.AsView.Left = InitialRightPosition
clvLeft.AsView.Visible = True
clvRight.AsView.Visible = True
'formula for determining spacing:
'Spacing = (ListView Height - (Widget Height x NumWidgets)) / NumWidgets
Dim Spacing As Int = (clvLeft.AsView.Height - (pnlWidget(0).Height * MaxWidgets)) / MaxWidgets
For I = 0 To MaxWidgets-1
Dim ItemPanel As Panel
Dim PanelIndex As Int = IndexMap.Get(I) 'Get the reference index from the hashtable
ItemPanel.Initialize("")
ItemPanel.SetLayout(0,0,pnlWidget(PanelIndex).Width, (Spacing + pnlWidget(PanelIndex).Height)) 'Create a panel and set the height of the panel the same as the Widget, plus the spacing.
ItemPanel.AddView(pnlWidget(PanelIndex), 0, (Spacing/2), pnlWidget(PanelIndex).Width, pnlWidget(PanelIndex).Height) 'Add the widget in the center of the panel
clvLeft.Add(ItemPanel, i) 'Add the new itempanel into the listview
Next
'Dump the excess off into the 2nd view
Spacing = (clvRight.AsView.Height - (pnlWidget(0).Height * (NumWidgetsNeeded - MaxWidgets))) / (NumWidgetsNeeded - MaxWidgets)
Dim I2 As Int = 0
For I = MaxWidgets To NumWidgetsNeeded-1
Dim ItemPanel As Panel
Dim PanelIndex As Int = IndexMap.Get(I) 'Get the reference index from the hashtable
ItemPanel.Initialize("")
ItemPanel.SetLayout(0,0,pnlWidget(PanelIndex).Width, (Spacing + pnlWidget(PanelIndex).Height)) 'Create a panel and set the height of the panel the same as the Widget, plus the spacing.
ItemPanel.AddView(pnlWidget(PanelIndex), 0, (Spacing/2), pnlWidget(PanelIndex).Width, pnlWidget(PanelIndex).Height) 'Add the widget in the center of the panel
clvRight.Add(ItemPanel, I2)
I2 = I2 + 1
Next
Else 'Everything should fit in a single listview.
clvRight.Clear
clvLeft.clear
'formula for determining spacing:
'Spacing = (ListView Height - (Widget Height x NumWidgets)) / NumWidgets
Dim Spacing As Int = (clvLeft.AsView.Height - (pnlWidget(0).Height * NumWidgetsNeeded)) / NumWidgetsNeeded
If Spacing < 0 Then Spacing = 0
For I = 0 To NumWidgetsNeeded-1
Dim PanelIndex As Int = IndexMap.Get(I) 'Get the reference index from the hashtable
Dim ItemPanel As Panel
ItemPanel.Initialize("")
ItemPanel.RemoveAllViews
ItemPanel.SetLayout(0,0,pnlWidget(PanelIndex).Width, (Spacing + pnlWidget(PanelIndex).Height)) 'Create a panel and set the height of the panel the same as the Widget, plus the spacing.
ItemPanel.AddView(pnlWidget(PanelIndex), 0, (Spacing/2), pnlWidget(PanelIndex).Width, pnlWidget(PanelIndex).Height) 'Add the widget in the center of the panel (THIS IS THE ERROR)
clvLeft.Add(ItemPanel, i)
'clvLeft.ResizeItem(i,pnlWidget(i).Height + Spacing)
Next
End If
Log("updatewidgets exited")
End Sub
And, here is the error:
B4X:
Updatewidgets called
0,2
updatewidgets exited
Updatewidgets called
0,2
1,5
Error occurred on line: 476 (Main)
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5034)
at android.view.ViewGroup.addView(ViewGroup.java:4865)
at android.view.ViewGroup.addView(ViewGroup.java:4837)
at anywheresoftware.b4a.objects.PanelWrapper.AddView(PanelWrapper.java:65)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1082)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1037)
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:144)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at edge.scoremonitor.scorewidget._connectionmanager_handleconnect(scorewidget.java:385)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
at anywheresoftware.b4a.debug.Debug.CallSubNew(Debug.java:282)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.keywords.Common.CallSubDebug(Common.java:1050)
at edge.scoremonitor.connectionmanager._parsedata(connectionmanager.java:446)
at edge.scoremonitor.connectionmanager._mqtt_messagearrived(connectionmanager.java:387)
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:144)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Any thoughts? Thanks