Create fragment in viewpager adapter when tab selected - android

There are two fragments inside viewPager. When the main fragment load the location permission code on the second fragment that work. Want that fragmen work when click the second tab. So I think I need to create this fragment when selected second tab. How can detect and do this?
OurHospitalFragment.kt
viewPager2OurHospital.adapter = adapter
viewPager2OurHospital.offscreenPageLimit = 1
TabLayoutMediator(tabLayoutOurHospital, viewPager2OurHospital) { tab, position ->
when (position) {
0 -> tab.text = getString(R.string.list)
1 -> tab.text = getString(R.string.map)
}
}.attach()
tabLayoutOurHospital.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.let {
viewPager2OurHospital.isUserInputEnabled = tab.position != 1
}
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
OurHospitalASMViewPagerAdapter.kt
class OurHospitalViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int {
return 2
}
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> HospitalListFragment()
1 -> HospitalMapFragment()
else -> Fragment()
}
}
}

I wrote this code line:
viewPager2OurHospital.offscreenPageLimit = ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
instead of this:
viewPager2OurHospital.offscreenPageLimit = 1
and I get it what I want.

Related

Infinite scroll in viewpager2 and tablayoutmediator

I'm trying to get bidirectional infinite scroll in my viewpager 2, but I can't seem to see how to reach the solution, so any help will be appreciated.
Adapter:
class LandingViewPagerAdapter(fa: FragmentActivity, val slides: List<DtoSlide>) :
FragmentStateAdapter(fa) {
override fun getItemCount(): Int {
return slides.size
}
override fun createFragment(position: Int): Fragment {
return LandingSlideFragment().newInstance(slides[position])
}
}
Activity:
private fun setupViewPager(slides: List<data.network.entities.DtoSlide>) {
pagerAdapter = LandingViewPagerAdapter(this, slides)
viewpager_landing.adapter = pagerAdapter
TabLayoutMediator(viewpager_dots, viewpager_landing) { tab, position -> }.attach()
}

Android viewpager2 tab layout with FragmentStateAdapter

I am using ViewPager2 with Tab Layout. Here is my MainFragment code -
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.viewPager.adapter = MyPagerAdapter(requireActivity())
TabLayoutMediator(
binding.tabLayout, binding.viewPager
) { tab, position ->
binding.viewPager.setCurrentItem(0, true)
when (position) {
0 -> tab.text = “Tab A”
1 -> tab.text = “Tab B”
}
}.attach()
}
private class MyPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private val items = 2
override fun getItemCount(): Int {
return items
}
override fun createFragment(position: Int): Fragment = when (position) {
0 -> FragmentA()
1 -> FragmentB()
else -> FragmentA()
}
}
I have 2 questions here -
override fun createFragment(position: Int): Fragment creates new instance of child fragments every time the MainFragment view is created. Is there no way to re-use an already existing instance of child fragment?
In my Navigation graph, I have the MainFragment and its children FragmentA and FragmentB. Why cant I use the Navigation action to open children from its parent? If yes, override fun createFragment(position: Int): Fragment needs a Fragment to be returned and findNavController().navigate() does not return anything. How do I do this?
you can follow this sample code, may this will help you
class TvShowsFragment : Fragment(R.layout.tvshows_fragment) {
private var _binding: TvshowsFragmentBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = TvshowsFragmentBinding.bind(view)
setUpViewPager()
setHasOptionsMenu(true)
}
private fun setUpViewPager() {
val viewPager = binding.vpTvShows
val tab = binding.tlTvShows
val adapterTv = TvAdapter(this)
viewPager.adapter = adapterTv
TabLayoutMediator(tab, viewPager) { tabText, position ->
tabText.text = when (position) {
0 -> getString(R.string.title_tvAiringToday)
1 -> getString(R.string.title_tvOnTheAir)
2 -> getString(R.string.title_popular)
3 -> getString(R.string.title_topRated)
else -> getString(R.string.title_tvAiringToday)
}
}.attach()
}
private inner class TvAdapter(fm: Fragment) : FragmentStateAdapter(fm) {
override fun getItemCount(): Int = 4
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> TvAiringTodayFragment()
1 -> TvOnTheAirFragment()
2 -> TvPopularFragment()
3 -> TvTopRatedFragment()
else -> TvAiringTodayFragment()
}
}
}

How do you refresh a view each time a user switches to a tab in a ViewPager2?

I have the following FragmentStateAdapter:
class TabPagerAdapter(activity: AppCompatActivity, private val itemsCount: Int) : FragmentStateAdapter(activity) {
override fun getItemCount(): Int {
return itemsCount
}
override fun createFragment(position: Int): Fragment {
val default = CreateFragment()
return when (position) {
0 -> default
1 -> {
ProjectFragment()
}
else -> default
}
}
}
How could I refresh a specific fragment (I only need this for ProjectFragment) each time a user swipes to this tab?
You can consider overriding onResume() method for ProjectFragment. Setting fields to null in onResume() might help.

In tab layout fragments not showing their layout in androidX

I have a tab layout in which I have included five fragments, but when i click on tabs, the fragments layout is not showed. In my adapter I've extended FragmentPagerAdapter which has FragmentManager and a variable behaviour.
class ViewPagerAdapter(#NonNull fm:FragmentManager, behaviour:Int):
FragmentPagerAdapter(fm, behaviour) {
private val tabs:Array<Fragment> = arrayOf(
Category1Fragment(),
Category2Fragment(),
Category3Fragment(),
Category4Fragment(),
Category5Fragment()
)
#NonNull
override fun getItem(position: Int): Fragment {
return tabs[position]
}
override fun getCount(): Int {
return tabs.size
}
#Nullable
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> "Bags"
1 -> "Watches"
2 -> "Shoes"
3 -> "Glasses"
4 -> "Audio"
else -> null
}
}
}
and in my activity I've called adapter through viewpager, but when I debug is telling me that adapter is null, here's my activity code:
val adapter = ViewPagerAdapter(supportFragmentManager, tab_layout.selectedTabPosition)
val viewPager = findViewById<ViewPager>(R.id.view_pager)
viewPager.adapter = adapter
val tab = findViewById<TabLayout>(R.id.tab_layout)
tab.setupWithViewPager(view_pager)
// -------------------------------------------------------------------------------- //
tab.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(p0: TabLayout.Tab?) {
}
override fun onTabUnselected(p0: TabLayout.Tab?) {
}
override fun onTabSelected(p0: TabLayout.Tab?) {
viewPager.currentItem = tab.selectedTabPosition
}
})
In the previous versions of android I did the same, but in androidX things are something different. I tried also to use ViewPager2, but it was confusing.
Any help is appreciated!

fragment inside fragment {Kotlin}

is there any possible way to put a fragment inside a fragment?
I tried to put a viewPager in a fragment and write the code on OnCreatedView but it gives me error!!!
I tried this one but the fragments goes for every fragment in the activity!
pageradapter.kt
class pagerAdapter(fm:FragmentManager):FragmentStatePagerAdapter(fm){
override fun getItem(position: Int): Fragment? {
return when(position){
0-> Fragment1()
1-> Fragment2()
else -> null
}
}
override fun getCount(): Int {
return 2
}
fun rotatePosition(position: Int):Int{
return (count -1)-position
}
class pagerAdapter(fm:FragmentManager):FragmentStatePagerAdapter(fm){
override fun getItem(position: Int): Fragment? {
return when(position){
0-> Fragment1()
1-> Fragment2()
else -> null
}
}
override fun getCount(): Int {
return 2
}
fun rotatePosition(position: Int):Int{
return (count -1)-position
}
pageradapter2.kt
class pagerAdapter2(fm: FragmentManager):FragmentStatePagerAdapter(fm){
override fun getItem(position: Int): Fragment? {
return when(position){
0-> BlankFragment()
else->null
}
}
/**
* Return the number of views available.
*/
override fun getCount(): Int {
return 1
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val pagerAdapter2 = pagerAdapter2(supportFragmentManager)
val pager1= findViewById<View>(R.id.pager2) as ViewPager
pager1.adapter = pagerAdapter2
val adapter = pagerAdapter(supportFragmentManager)
val pager = findViewById<View>(R.id.pager) as ViewPager
pager.adapter = adapter
pager.setCurrentItem(adapter.rotatePosition(0), false)
}
P.S. The first Answer solved my problem.
If you are adding fragment for an activity you use either fragmentManager or supportFragmentManager.
If you are adding fragment for a fragment - you should use childFragmentManager, accessing fragmentManager from fragment will lead to using the same one that activity does.

Categories

Resources