During the basic training in Amir_RecyclerView (ARV), a small test project was created, which may help RV newcomers to familiarize themselves with RecyclerViews.
Topic: "React to clickevents, change data and update the list"
Edit: The attached testproject was updated. Now the proposal of @alimanam3386 to notify the adapter after changing the DataSet is integrated.
Topic: "React to clickevents, change data and update the list"
B4X:
#Region Project Attributes
#ApplicationLabel: B4A Example
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
' ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--..
'
' Ref1) Info lib --> https://www.b4x.com/android/forum/threads/lib-chargeable-amir_recyclerview.97274/#post-613329
'
' Ref2) Info Android Dev --> https://developer.android.com/reference/android/support/v7/widget/RecyclerView
'
' Ref3) Info Codepath RV --> https://guides.codepath.com/android/Using-the-RecyclerView
'
' ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--.. ~~--..
'
#Region ---- Relationship of the RV components ----
' +----------------------+
' | RecyclerView |
' | |
' | |
' |+--------------------+| +--------------+ +-------------+
' || LayoutManager || | | | |
' || || | | | |
' || || | | | |
' || -----| Adapter |--| DataSet |
' || || | | | |
' || || | | | |
' |+--------------------+| | | | |
' +----------------------+ +--------------+ +-------------+
' Created with --> http://www.torchsoft.com/en/aas_information.html
#end region
Sub Process_Globals
End Sub
Sub Globals
Type arvItem(Title As String, Description As String)
Private arv As Amir_RecyclerView
Private DataSet As List
End Sub
Sub Activity_Create(FirstTime As Boolean)
Log("#-Sub Activity_Create")
Activity.Color = Colors.White
arvBuild
arvFill
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
'
Sub arvBuild
Log("#-Sub arvBuild")
arv.Initializer("arv").ListView.Build
arv.DefaultAdapter
Activity.AddView(arv, 0, 0, 100%x, 100%y)
End Sub
Sub arvFill
Log("#-Sub arvFill")
DataSet.Initialize
For i = 0 To 9
Dim arvItemX As arvItem
arvItemX.Initialize
arvItemX.Title = "Entry " & i
arvItemX.Description = "Lorem ipsum to entry " & i
DataSet.Add(arvItemX)
Next
arv.Adapter2.NotifyDataSetChanged
End Sub
Sub arv_GetItemCount As Int
Log("#-Sub arv_GetItemCount, DataSet.Size=" & DataSet.Size)
Return DataSet.Size ' This is for the Adapter
End Sub
Sub arv_onCreateViewHolder (Parent As Panel, ViewType As Int)
Log("#-Sub arv_onCreateViewHolder, ViewType=" & ViewType)
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
' This creates a panel for each list item without filling in the content
' The content will be filled later in "..._onBindViewHolder"
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
Parent.LoadLayout("1")
End Sub
Sub arv_onBindViewHolder (Parent As Panel, Position As Int)
Log("#-Sub arv_onBindViewHolder, Position=" & Position)
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
' This fills the item content from the Dataset
' corresponding to the position
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
Dim panBack As Panel = Parent.GetView(0)
Dim Label1 As Label = panBack.GetView(0)
Dim Label2 As Label = panBack.GetView(1)
Dim arvItemX As arvItem = DataSet.Get(Position)
'
Label1.Text = arvItemX.Title
Label2.Text = arvItemX.Description & CRLF & "Position=" & Position
panBack.Height = Label1.Height +Label2.Height +(Label1.Top *2)
Parent.Height = panBack.Height +8dip
End Sub
Sub arv_onItemClick (Parent As Panel, Position As Int)
Log("#-Sub arv_onItemClick, Position=" & Position)
'--- --- --- --- --- --- --- --- --- --- --- --- ---
'Example: CHANGE content in underlying Data
' and inform the Adapter
'--- --- --- --- --- --- --- --- --- --- --- --- ---
Dim arvItemX As arvItem = DataSet.Get(Position)
arvItemX.Title = arvItemX.Title & ", click"
DataSet.Set(Position, arvItemX)
arv.Adapter2.NotifyDataItemChanged(Position)
'--- --- --- --- --- --- --- --- --- --- --- --- ---
End Sub
Sub arv_onItemLongClick (Parent As Panel, Position As Int) As ResumableSub
Log("#-Sub arv_onItemLongClick, Position=" & Position)
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
' Example: DELETE content in underlying Data
' and inform the Adapter
' --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
Dim arvItemX As arvItem = DataSet.Get(Position)
Msgbox2Async($"Delete the item '${arvItemX.Title}'?"$, $"Delete item '${arvItemX.Title}'"$, "Yes", "Cancel", "No", Null, False)
Wait For Msgbox_Result (Result As Int)
If Result = DialogResponse.POSITIVE Then
DataSet.RemoveAt(Position)
arv.Adapter2.NotifyItemRemoved(Position)
arv.Adapter2.NotifyDataItemChanged2(Position, Position +arv.GetVisibleItemCount) ' Needed to inform the Layout manager to refresh the visible items BELOW the clicked item
ToastMessageShow($"'${arvItemX.Title}' removed from list"$, False)
End If
Return Null
End Sub
Edit: The attached testproject was updated. Now the proposal of @alimanam3386 to notify the adapter after changing the DataSet is integrated.
In principle, you should notify the adapter after a change to the DataSet so that a suitable animation is displayed and the administration cache of the displayed items is updated:
B4X:
DataSet.RemoveAt(Position)
arv.Adapter2.NotifyItemRemoved(Position)
arv.Adapter2.NotifyDataItemChanged2(Position, Position +arv.GetVisibleItemCount) ' Needed to inform the Layout manager to refresh the visible items BELOW the clicked item
Attachments
Last edited: