Hi, I have migrated to ViewPager2 as the main widget on my application. This time, I have some problems that can't find any idea.
Firstly, I created the adapter using a list of GroupData, something like.
data class GroupData(var groupName: String?, val tags: MutableList<TagData>)
@Parcelize
data class TagData(
var id: String?,
var table: String?,
var groupName: String?,
var tagName: String,
var display: String?,
var isCanWritable: Boolean = false,
var type: String? = null,
var swipeOffSet: Int? = 0,
var inputType: Int? = null,
var defaultListValues: List? = null
) : Parcelable
This is my adapter
class GroupTabPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private val differ = AsyncListDiffer(this, DIFF_CALLBACK)
companion object {
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<GroupData>() {
override fun areItemsTheSame(oldItem: GroupData, newItem: GroupData) =
oldItem.groupName == newItem.groupName
override fun areContentsTheSame(oldItem: GroupData, newItem: GroupData): Boolean {
val oldTags = oldItem.tags
val newTags = newItem.tags
// check collections aren't same
if (oldTags.size != newTags.size) return false
newTags.forEachIndexed { index, newTag ->
val oldTag = oldTags.getOrNull(index) ?: return false
if (newTag != oldTag) { return false }
}
return true
}
}
}
/**
* Get Current list data of pager
*/
fun getCurrentList(): MutableList<GroupData> = differ.currentList
/**
* Use DiffUtil to calculate and notify data
*/
fun summitList(newData: List<GroupData>) {
differ.submitList(newData)
}
override fun getItemCount() = differ.currentList.size
override fun createFragment(position: Int) = GroupTabFragment.newInstance(
differ.currentList[position].groupName,
differ.currentList[position].tags
)
// override fun getItemId(position: Int) = differ.currentList[position].hashCode().toLong()
//
// override fun containsItem(itemId: Long) =
// differ.currentList.map { it.hashCode().toLong() }.contains(itemId)
}
OK, the problems are.
Our app has the `TabLayout` and `ViewPager2`, that the tab will show the list of GroupName -> groupName
And GroupTabFragment is an item per page of ViewPager2, in this sample, I will put all the data of TagData list into `GroupTabFragment`
This fragment contains only `RecyclerView` and displays the list of TagData correctly on the first time summit list.
When the data has changed, something like I want to delete some specific group data, I remove some item of `List<GroupData>`, then `summitList` again. It makes a tab layout change correctly
Ex:
ListGroupData : [{"A",tags: ["Tag A", "Tag B", "Tag C"]}, {"B",tags: ["Tag BB", "Tag CC", "Tag EE"]} ]
changed to
ListGroupData : [{"B",tags: ["Tag BB", "Tag CC", "Tag EE"]} ]
It must display 1 tab named "B" and show the list inside Fragment with "Tag BB", "Tag CC", "Tag EE" data. But, now it displays correctly tab name, but still, keep the old list inside Fragment "Tag A", "Tag B", "Tag C"
-----
I have made another solution is comment-out 2 override-methods`getItemId` and `containsItem` and it can work correctly, checking the log means that the Fragment will be detached and re-attacted again. However, this Fragment is in not yet attached Activity state, I mean sometimes, when called getActivity(), it always returns `null`
Does anyone have the same this issue?
Hi, I have migrated to ViewPager2 as the main widget on my application. This time, I have some problems that can't find any idea.
@Parcelize data class TagData( var id: String?, var table: String?, var groupName: String?, var tagName: String, var display: String?, var isCanWritable: Boolean = false, var type: String? = null, var swipeOffSet: Int? = 0, var inputType: Int? = null, var defaultListValues: List? = null
) : Parcelable
class GroupTabPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
// override fun getItemId(position: Int) = differ.currentList[position].hashCode().toLong() // // override fun containsItem(itemId: Long) = // differ.currentList.map { it.hashCode().toLong() }.contains(itemId) }