I am using Navigation component in my App, using google Advanced Sample(here). my problem is when going back to a fragment, RecyclerView rearranges items and moves highest visible items so that top of those item align to top of recyclerview. please see this:
before going to next fragment:
and after back to fragment:
this problem is matter because some times clicked item goes down and not seen until scroll down. how to prevent this behavior?
please consider:
-
this problem exist if using navigation component to change fragment. if start fragment using
supportFragmentManager.beginTransaction()
or start another activity and then go to this fragment it is OK. but if I navigate to another fragment using navigation component this problem is exist.(maybe because of recreating fragment) -
also this problem exist if using fragment in ViewPager. i.e recyclerView is in a fragment that handle with ViewPagerAdapter and viewPager is in HomeFragment that opened with Navigation component. if recyclerView is in HomeFragment there is no problem.
-
no problem with LinearLayoutManager. only with StaggeredGridLayoutManager.
-
there is not difference if using ViewPager2 and also FragmentStatePagerAdapter
-
I try to prevent recreate of fragment(by this solution) but not solved.
code is:
class HomeFragment : BaseFragment() {
override val layout = R.layout.fragment_home
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupViewPager()
}
private fun setupViewPager() {
val tab1 = tabLayout.newTab()
tab1.text = "Test2"
tabLayout.addTab(tab1, 0, true)
val tab2 = tabLayout.newTab()
tab2.text = "Test1"
tabLayout.addTab(tab2, 1, true)
val adapter = StreamPagerAdapter(
childFragmentManager, listOf(
ApiUrls.FRIENDS_STREAM_URL,
ApiUrls.CHOICES_STREAM_URL,
ApiUrls.LATEST_STREAM_URL,
)
)
homeViewPager.adapter = adapter
}
}
pager adapter:
class StreamPagerAdapter(fragmentManager: FragmentManager, val urlList: List<String>) :
FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getCount(): Int {
return urlList.size
}
override fun getItem(position: Int): Fragment {
return TestFragment().newInstance(urlList[position])
}
}
fragment:
class TestFragment : Fragment() {
fun newInstance(streamUrl: String): TestFragment {
val fragment = TestFragment()
val args = Bundle()
args.putString(Arguments.POST_LIST_URL, streamUrl)
fragment.arguments = args
return fragment
}
val viewModel by viewModel<HomeViewModel>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragmetn_test, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
postListView.apply {
layoutManager = StaggeredGridLayoutManager(
2, StaggeredGridLayoutManager.VERTICAL
).apply {
gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
}
setHasFixedSize(true)
adapter = TestListAdapter()
}
}
}
RecyclerView adapter:
class TestListAdapter: RecyclerView.Adapter<TestListAdapter.ListViewHolder>(){
private val itemList = listOf(
TestModel(Color.BLUE, 340),
TestModel(Color.CYAN, 500),
TestModel(Color.DKGRAY, 450),
TestModel(Color.GREEN, 660),
TestModel(Color.WHITE, 620),
TestModel(Color.YELLOW, 550),
TestModel(Color.BLACK, 390),
TestModel(Color.GRAY, 430),
TestModel(Color.RED, 230),
TestModel(Color.MAGENTA, 420),
TestModel(Color.GREEN, 360),
)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view =
DataBindingUtil.inflate<TestListItemBinding>(
inflater,
R.layout.test_list_item,
parent,
false
)
return ListViewHolder(binding = view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val testView = holder.itemView.testView
testView.setBackgroundColor(itemList[position].color)
val params: ViewGroup.LayoutParams = testView.layoutParams
params.height = itemList[position].height
holder.binding.executePendingBindings()
}
override fun getItemCount() = itemList.size
class ListViewHolder(var binding: TestListItemBinding) : RecyclerView.ViewHolder(binding.root)
data class TestModel(val color: Int, val height: Int)
}
from RecyclerView with StaggeredGridLayoutManager in ViewPager, arranges items automatically when going back to fragment
No comments:
Post a Comment