Android Question Multiple CheckBox in CustomListView

Status
Not open for further replies.

Johan Hormaza

Well-Known Member
Licensed User
Hello!
How can I configure multiple CheckBox in an xCLV, but only one is enabled in the list, for example:
That if I have a CheckBox for each article, I can enable only one and that when I enable another; The one that was already changed to disabled.
Only one enabled in the entire list until you choose another.
Thank you!
 

Erel

Administrator
Staff member
Licensed User
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   For i = 1 To 100
       Dim p As B4XView = xui.CreatePanel("")
       p.SetLayoutAnimated(0, 0, 0, CustomListView1.AsView.Width, 50dip)
       Dim chk As CheckBox
       chk.Initialize("chk")
       p.AddView(chk, 10dip, 10dip, 30dip, 30dip)
       CustomListView1.Add(p, "")
   Next
End Sub

Sub chk_CheckedChange(Checked As Boolean)
   If Checked Then
       Dim ItemIndex As Int = CustomListView1.GetItemFromView(Sender)
       For i = 0 To CustomListView1.Size - 1
           Dim p As B4XView = CustomListView1.GetPanel(i)
           If i <> ItemIndex Then
               p.GetView(0).Checked = False
           End If
       Next
   End If
End Sub
 

udg

Expert
Licensed User
Or..if you really have a large number of items, just keep a Global var as the index of the currently checked item and in the CheckedChange event pick it up, set its state to False and store the new index as the currently selected one.
As alwyas there are pros and cons.
 

Johan Hormaza

Well-Known Member
Licensed User
When I add a design to Custom ListView I have this problem. What can be?

main_chk_checkedchange (java line: 506)
java.lang.ClassCastException: android.widget.TextView cannot be cast to android.widget.CompoundButton
at anywheresoftware.b4a.objects.B4XViewWrapper.setChecked(B4XViewWrapper.java:270)
at b4a.example.checkbox.main._chk_checkedchange(main.java:506)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.objects.CompoundButtonWrapper$1.onCheckedChanged(CompoundButtonWrapper.java:44)
at android.widget.CompoundButton.setChecked(CompoundButton.java:156)
at android.widget.CompoundButton.toggle(CompoundButton.java:115)
at android.widget.CompoundButton.performClick(CompoundButton.java:120)
at android.view.View$PerformClick.run(View.java:21163)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
** Activity (main) Resume **
 

Johan Hormaza

Well-Known Member
Licensed User
Ok, problem solved.
I did it this way and it worked!
B4X:
If Checked Then
            Dim ItemIndex As Int = CustomListView1.GetItemFromView(Sender)
            For i = 0 To CustomListView1.Size - 1
                Dim p As B4XView = CustomListView1.GetPanel(i)
                If i <> ItemIndex Then
                    For Each v As View In p.GetAllViewsRecursive
                        If v Is CheckBox Then
                            p.GetView(0).Checked = False
                        End If
                    Next
                End If
            Next
        End If
 

mangojack

Well-Known Member
Licensed User
Ok, problem solved.
I did it this way and it worked!
If you already know the Checkbox is the first view (0) on the Item / row panel ... there is now need to iterate thru all panel views. See @Erel 's code above.
Also , I would only declare a panel if the Index did not equal ItemIndex.

B4X:
If Checked Then
  Dim ItemIndex As Int = CustomListView1.GetItemFromView(Sender)
  For i = 0 To CustomListView1.Size - 1
    If  i <> ItemIndex Then      
      Dim p As B4XView = CustomListView1.GetPanel(i)
      p.GetView(0).Checked = False
    End If
  Next
End If
 

gpbimal

Member
Hi!
I'm using CustomListView with multiple rows (about 50 student name list and Checkbox for every students) for daily attendance. My CheckBox name is chkAtn and I've bind the student ID to corresponding Checkbox.Tag. When application starts all checkbox will be checked = true by default. Class teacher will uncheck for absent student only at the time of attendance.

Now I have to collect absent student's ID in a list(log). Please help...

Multiple Checkbox with CustomListView:
Sub Make_Post
For i = 0 To CLVstd.Size - 1
    If chkAtn.Checked = False Then
        Log(chkAtn.tag)
    End If
Next
End Sub

If full code required then,
B4X:
#Region Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
    Public SPHost As String
    Private GET_CLASS = "get_class", GET_STUDENTS = "get_students" As String
    Type ItemValue (SelChkBox As CheckBox)
End Sub

Sub Globals
    Private spnClass As Spinner
    Dim ClasCode As Map
    Dim CID As Double
    Private CLVstd As CustomListView
    Dim XUI As XUI
    
    Private lblStdInfo As Label
    Private chkAtn As CheckBox
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("LayAttendance")
    ClasCode.Initialize
    Show_Clases
End Sub

Sub Show_Clases
    ExecuteRemoteQuery("Select engname, classid from classid order by classid", GET_CLASS)
End Sub

Sub Show_Students
    ExecuteRemoteQuery("SELECT infocustomer.engname, infostudent.TheRollNo, infostudent.CustIDNO FROM infostudent, infocustomer WHERE (infocustomer.CustIDNO = infostudent.CustIDNO) AND (infostudent.TheSection = 'A') AND (infostudent.ClassId = " & CID & ") ORDER BY infostudent.TheRollNo", GET_STUDENTS)
End Sub

Sub ExecuteRemoteQuery(Query As String, JobName As String)
    Try
        'ProgressDialogShow("Connecting to server...")
        Dim job As HttpJob
        job.Initialize(JobName, Me)
        job.PostString(SPHost, Query)
    Catch
        Log(LastException)
    End Try
End Sub

Sub JobDone(Job As HttpJob)
    'ProgressDialogHide
    If Job.Success Then
        Dim res As String
        res = Job.GetString
        Log("Response from server: " & res)
        Dim Parser As JSONParser
        Parser.Initialize(res)
        Select Job.JobName
            Case GET_CLASS
                Dim l As List
                l = Parser.NextArray
                If l.Size > 0 Then
                    For i = 0 To l.Size - 1
                    Dim m As Map
                    m = l.Get(i)
                    spnClass.Add(m.Get("engname"))
                    ClasCode.Put(m.Get("engname"), m.Get("classid"))
                    Next
                End If
            Case GET_STUDENTS
                Dim l As List
                l = Parser.NextArray
                If l.Size > 0 Then
                    CLVstd.Clear
                    For i = 0 To l.Size - 1
                        Dim m As Map
                        Dim TheCID As Double
                        m = l.Get(i)
                        Dim p As B4XView = XUI.CreatePanel("")
                        p.SetLayoutAnimated(0, 0, 0, CLVstd.AsView.Width, 50dip)
                        chkAtn.Initialize("chkAtn")
                        chkAtn.Checked = True
                        TheCID = m.Get("CustIDNO")
                        CLVstd.Add(CreateListItem(m.Get("TheRollNo") & " :     " & m.Get("engname") , CLVstd.AsView.Width, 60dip), TheCID)
                    Next
                End If
        End Select
    Else
        Log(Job.ErrorMessage)
        ToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If
    Job.Release
End Sub

Sub spnClass_ItemClick (Position As Int, Value As Object)
    CID = ClasCode.Get(Value)
    Log(CID)
    Show_Students
End Sub

Sub CreateListItem(Text As String, Width As Int, Height As Int) As Panel
    Dim p As B4XView = XUI.CreatePanel("")
    p.SetLayoutAnimated(0, 0, 0, Width, Height)
    p.LoadLayout("LayControl")
    lblStdInfo.Text = Text
    Return p
End Sub

Sub CLVstd_ItemClick (Index As Int, Value As Object)

End Sub

Sub Make_Post
For i = 0 To CLVstd.Size - 1
    If chkAtn.Checked = False Then
        Log(chkAtn.tag)
    End If
Next
End Sub

Sub btnPost_Click
    Make_Post
End Sub
 
Status
Not open for further replies.
Top