I would like to create an recyclerView in a fragment, but it shows an error " java.lang.IllegalStateException: recylerView_Main must not be null
at com.gph.bottomnavigation.FragmentMe.onCreateView(FragmentMe.kt:28)"
Question 1) Please kindly help to solve this issue.
Question 2) I created an recyclerView only in a empty project without any fragment, it is working properly.
But the same code is no working in Fragment, it shows error so I change "recylerView_Main.layoutManager = LinearLayoutManager(this)" to "recylerView_Main.layoutManager = LinearLayoutManager(context)"
It shows no error and I can run in simlulator, but when I click the navigation button of the Fragment, the app stops and show this error. Please kindly help to solve it.
Here with the code for FragmentMe.kt:
class FragmentMe : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
recylerView_Main.layoutManager = LinearLayoutManager(context)
recylerView_Main.adapter = Mainadapter()
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_me, container, false)
}
}
Here with the code of MainActivity.kt:
class MainActivity : AppCompatActivity() {
val manager = supportFragmentManager
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
//message.setText(R.string.title_home)
createFragmentQpon()
return#OnNavigationItemSelectedListener true
}
R.id.navigation_dashboard -> {
//message.setText(R.string.title_dashboard)
createFragmentMe()
return#OnNavigationItemSelectedListener true
}
R.id.navigation_notifications -> {
//message.setText(R.string.title_notifications)
createFragmentTools()
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Action Bar
val actionBar = supportActionBar
actionBar!!.setDisplayShowHomeEnabled(true)
actionBar.setBackgroundDrawable(ColorDrawable(Color.parseColor("#00FFFFFF")))
actionBar.setIcon(R.drawable.ic_home_black_24dp)
actionBar.setDisplayShowTitleEnabled(false)
createFragmentQpon()
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
fun createFragmentQpon() {
val transaction = manager.beginTransaction()
val fragment = FragmentQpon()
transaction.replace(R.id.fragmentholder,fragment)
transaction.addToBackStack(null)
transaction.commit()
}
fun createFragmentMe() {
val transaction = manager.beginTransaction()
val fragment = FragmentMe()
transaction.replace(R.id.fragmentholder,fragment)
transaction.addToBackStack(null)
transaction.commit()
}
fun createFragmentTools() {
val transaction = manager.beginTransaction()
val fragment = FragmentTools()
transaction.replace(R.id.fragmentholder,fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
Here with the code of Mainadapter.kt:
class Mainadapter: RecyclerView.Adapter<CustomViewHolder>() {
val videolist = listOf("aaa","bbbb","cccc")
override fun getItemCount(): Int {
return 3
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent?.context)
val cellForRow = layoutInflater.inflate(R.layout.tutorial_layout, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
var videoName = videolist.get(position)
holder.itemView.title.text = videoName
}
}
class CustomViewHolder(v: View): RecyclerView.ViewHolder(v) {
}
Move this code
recylerView_Main.layoutManager = LinearLayoutManager(context)
recylerView_Main.adapter = Mainadapter()
from onCreateView to onActivityCreated
override onActivityCreated and place the above code.
There are two things incorrect in your code :
You are trying to access recyclerView even before inflating the View.
The context of a Fragment is null in onCreateView and is usable in between onAttach and onDetach
recylerView_Main.layoutManager = LinearLayoutManager(this.context)
Try this out, worked fine for me.
Related
I have a settings screen which has a FrameLayout that loads a fragment containing a RecyclerView. The RecyclerView has selectable items, which are handled by the onItemClick function inside the fragment.
The objective, is to replace the current opened fragment with another one.
Is it possible to replace the current fragment while in the onItemClick function? If so, how?
Code
Fragment used for handling the RecyclerView and the onItemClick function
class FragmentSettingsMain : Fragment(), AdapterSettings.OnItemClickListener {
lateinit var settingsList: List<DataItemsSettings>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
settingsList = listOf(
DataItemsSettings(getString(R.string.look), getString(R.string.lookdescription), R.drawable.ic_colored_color_lens),
DataItemsSettings(getString(R.string.playing), getString(R.string.playingdescription), R.drawable.ic_colored_view_carousel),
DataItemsSettings(getString(R.string.images), getString(R.string.imagesdscription), R.drawable.ic_colored_image),
DataItemsSettings(getString(R.string.audio), getString(R.string.audiodescription), R.drawable.ic_colored_volume_up),
DataItemsSettings(getString(R.string.other), getString(R.string.otherdescription), R.drawable.ic_colored_shape),
DataItemsSettings(getString(R.string.about), getString(R.string.aboutdescription), R.drawable.ic_colored_info)
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_settings_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvSettings.apply {
layoutManager = LinearLayoutManager(activity)
adapter = AdapterSettings(settingsList, this#FragmentSettingsMain)
}
}
override fun OnItemClick(position: Int) {
when(position) {
0 -> //NEED TO REPLACE FRAGMENT HERE
1 -> //NEED TO REPLACE FRAGMENT HERE
2 -> //NEED TO REPLACE FRAGMENT HERE
3 -> //NEED TO REPLACE FRAGMENT HERE
4 -> //NEED TO REPLACE FRAGMENT HERE
5 -> this.startActivity(Intent(context, ActivityAbout::class.java))
}
}
}
Activity where the FrameLayout is
class ActivitySettings : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
topToolbarBack.setNavigationOnClickListener {
finish()
}
val frgSettingsMain = FragmentSettingsMain()
setCurrentFragment(frgSettingsMain)
}
private fun setCurrentFragment(fragment: Fragment) =
supportFragmentManager.beginTransaction().apply {
replace(R.id.framelayoutSettings, fragment)
commit()
}
}
You can try this
override fun OnItemClick(position: Int) {
when(position) {
0 -> addContentFragment(yourFragment(),true)
1 -> //NEED TO REPLACE FRAGMENT HERE
2 -> //NEED TO REPLACE FRAGMENT HERE
3 -> //NEED TO REPLACE FRAGMENT HERE
4 -> //NEED TO REPLACE FRAGMENT HERE
5 -> this.startActivity(Intent(context, ActivityAbout::class.java))
}
}
fun addContentFragment(fragment: androidx.fragment.app.Fragment?, addToBackStack: Boolean) {
activity?.let {it->
if (!it.isFinishing) {
if (fragment == null) {
return
}
it.supportFragmentManager.let {it1->
val fragmentManager =it.supportFragmentManager
val currentFragment =
fragmentManager.findFragmentById(R.id.framelayoutSettings)
if (currentFragment != null && fragment.javaClass.isAssignableFrom(
currentFragment.javaClass
)
) {
return
}
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.add(
R.id.framelayoutSettings,
fragment,
fragment.javaClass.name
)
if (addToBackStack) {
fragmentTransaction.addToBackStack(fragment.javaClass.name)
}
fragmentTransaction.commit()
}
}
}
}
I am getting exception:
E/MessageQueue-JNI: java.lang.IllegalArgumentException: No view found for id 0x7f0a0554 (ua.com.company.app:id/vpBanners) for fragment BannerItemFragment{30698be} (4c80b228-4303-4c80-b99d-a55b8359b8c2) id=0x7f0a0554}
My hierarchy looks like so:
My adapter for vpHome:
class HomeViewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val mFragmentList: MutableList<Fragment> = ArrayList()
private val mFragmentTitleList: MutableList<String> = ArrayList()
override fun getItem(position: Int): Fragment {
return mFragmentList[position]
}
override fun getCount(): Int {
return mFragmentList.size
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList[position]
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
}
And I apply it in this way:
private fun setupViewPager(viewPager: DisableSwipeViewPager) {
vpAdapter = HomeViewPagerAdapter(childFragmentManager).apply {
addFragment(ForYouFragment(), "for you")
addFragment(AnotherFragment1(), "a1")
addFragment(AnotherFragment2(), "a2")
}
viewPager.adapter = vpAdapter
}
Next, my SnapBannersCarouselViewHolder to handle items with ViewPager inside:
class SnapBannersCarouselViewHolder(
private val mBinding: HomeFragmentItemSnapBannersCarouselBinding
) : RecyclerView.ViewHolder(mBinding.root) {
companion object {
// ...
fun newInstance(
inflater: LayoutInflater,
parent: ViewGroup,
onMoreInteractionListener: ((infoBlockId: String) -> Unit)?
): SnapBannersCarouselViewHolder {
val binding =
HomeFragmentItemSnapBannersCarouselBinding.inflate(inflater, parent, false)
return SnapBannersCarouselViewHolder(
binding,
onMoreInteractionListener
)
}
}
fun bind(item: SnapBannersItem, fragmentManager: FragmentManager) {
// ...
val adapter = BannerPagesAdapter(fragmentManager, item.banners)
with(mBinding.vpBanners) {
// ...
this.adapter = adapter
offscreenPageLimit = 3
}
}
}
My RecyclerView adapter ForYouContentAdapter:
class ForYouContentAdapter(
var data: List<HomeBaseItem> = emptyList(),
var fragmentManagerRetriever: () -> FragmentManager
) : BaseRecyclerViewAdapter<HomeBaseItem>(data) {
enum class ViewType(val value: Int) {
// ...
SNAP_BANNERS(6)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
// ...
ViewType.SNAP_BANNERS.value -> SnapBannersCarouselViewHolder.newInstance(
mInflater!!,
parent,
onBannersMoreInteractionListener // todo possibly change it
)
else -> throw RuntimeException("Can not create view holder for undefined view type")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
// ...
ViewType.SNAP_BANNERS.value -> {
val vHolder = holder as SnapBannersCarouselViewHolder
vHolder.bind(
getItem(position) as SnapBannersItem,
fragmentManagerRetriever.invoke()
)
}
}
}
}
And my fragmentManagerRetriever implementation in ForYouFragment looks like so:
private val fragmentManagerRetriever: () -> FragmentManager = {
childFragmentManager
}
My BannerItemFragment code:
class BannerItemFragment : Fragment() {
private lateinit var mBinding: HomeFragmentSnapBannerItemBinding
companion object {
// ...
fun newInstance(
item: RectWebViewItem
): BannerItemFragment {
return BannerItemFragment()
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mBinding = HomeFragmentSnapBannerItemBinding.inflate(inflater, container, false)
return mBinding.root
}
// ...
}
In every place where I need to create fragments inside other fragments I am using childFragmentManager.
And when I open ForYouFragment first time, it works normally. My item with ViewPager works normally. But when I replace fragment in Activity's container (adding to back stack) being on ForYouFragment and then return back (back on HomeFragment because ForYouFragment inside HomeFragment), I am getting error.
To replace fragments I am using this method inside ForYouFragment:
private fun showAnotherFragment() {
ActivityUtils.replaceFragmentToActivity(
requireActivity(),
SomeFragment.newInstance(),
true
)
}
And ActivityUtils code:
object ActivityUtils {
fun replaceFragmentToActivity(
activity: FragmentActivity,
fragment: Fragment,
addToBackStack: Boolean
) {
replaceFragmentToActivity(activity, fragment, addToBackStack, containerId = R.id.fragmentContainer)
}
fun replaceFragmentToActivity(
activity: FragmentActivity,
fragment: Fragment,
addToBackStack: Boolean,
containerId: Int
) {
val fragmentManager = activity.supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.replace(containerId, fragment)
if (addToBackStack) {
transaction.addToBackStack(null)
}
transaction.commitAllowingStateLoss()
}
}
Please, help me understand why I am getting this exception?
UPD
Adapter for ViewPager inside RecyclerView:
class BannerPagesAdapter(
fragmentManager: FragmentManager,
var data: List<RectWebViewItem>
) : FragmentStatePagerAdapter(
fragmentManager,
BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
) {
private var fragments: MutableList<BannerItemFragment> = mutableListOf()
init {
// initial empty fragments
for (i in data.indices) {
fragments.add(BannerItemFragment())
}
}
override fun getItem(position: Int): Fragment {
return BannerItemFragment.newInstance(data[position])
}
override fun getCount(): Int {
return fragments.size
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val f = super.instantiateItem(container, position)
fragments[position] = f as BannerItemFragment
return f
}
}
Solved
The problem was that fragments want to be attached to the ViewPager before the ViewPager is attached to its parent. This question outlined here.
So, to solve this problem, I created custom ViewPager:
/**
* Use this ViewPager when you need to place ViewPager inside RecyclerView.
* [LazyViewPager] allows you to set [PagerAdapter] in lazy way. This prevents IllegalStateException
* in case when the fragments want to be attached to the viewpager before the viewpager is
* attached to its parent
*/
class LazyViewPager
#JvmOverloads
constructor(
context: Context,
attrs: AttributeSet? = null
) : ViewPager(context, attrs) {
private var mPagerAdapter: PagerAdapter? = null
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (mPagerAdapter != null) {
super.setAdapter(mPagerAdapter)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
super.setAdapter(null)
}
#Deprecated("Do not use this method to set adapter. Use setAdapterLazy() instead.")
override fun setAdapter(adapter: PagerAdapter?) {}
fun setAdapterLazy(adapter: PagerAdapter?) {
mPagerAdapter = adapter
}
}
And then, instead of using setAdapter() I use setAdapterLazy().
Also, it is important to reset adapter to null in onDetachedFromWindow().
i am trying to code my app in kotlin but i am getting null cannot be casted to non-null type and it force my app to close. i tried to reference to other stackoverflow where they shift the init but i do not have any init portion in my current code. any help will be appreciated thank you.
reminder_fragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val v = inflater.inflate(R.layout.reminder_fragment, container, false)
//getting recyclerview from xml
val recyclerView = v.findViewById(R.id.reminderrecycler) as RecyclerView
//adding a layoutmanager
recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL ,false)
//crating an arraylist to store users using the data class user
val reminderlist = ArrayList<reminders>()
//adding some dummy data to the list
reminderlist.add(reminders("Belal Khan"))
reminderlist.add(reminders("Ramiz Khan"))
reminderlist.add(reminders("Faiz Khan"))
reminderlist.add(reminders("Yashar Khan"))
//creating our adapter
val adapter = CustomAdapter(reminderlist)
//now adding the adapter to recyclerview
recyclerView.adapter = adapter
return v;
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
val manager = supportFragmentManager
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_reminders -> {
createReminderFragment()
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bottom_navigation.setItemIconTintList(null);
createReminderFragment()
bottom_navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
/*private fun replaceFragment(fragment: Fragment) {
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragmentplaceholder, fragment)
fragmentTransaction.commit();
}*/
fun createReminderFragment() {
val transaction = manager.beginTransaction()
val fragment = reminder_fragment()
transaction.replace(R.id.fragmentplaceholder, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
reminder_fragment.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".reminder_fragment"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/reminderrecycler"/>
</LinearLayout>
CustomAdapter.kt
class CustomAdapter(val reminderlist: ArrayList<reminders>) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.reminder_fragment, parent, false)
return ViewHolder(v);
}
override fun getItemCount(): Int {
return reminderlist.size }
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(reminderlist[position])
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(reminders: reminders) {
val medicineText = itemView.findViewById(R.id.medicineText) as TextView
medicineText.text = reminders.medicineN
}
}
}
You does not implement your RecyclerView well.
You must have an seperated layout for RecyclerView items .
You set your RecyclerView items layout , your layout which your RecylerView decalared in it now .
Therefor android can not find your TextView with Id medicineText
I recommend you to do these:
1) Create a seperate layout for your RecyclerView items and inflate it to your holder as below :
val v = LayoutInflater.from(parent.context).inflate(R.layout.recylerView_item, parent, false)
2) put in an TextView in RecylerView item layout with id of medicineText
3)Use ? symbol to handle possible NullPonterException when you declaring your TextView
val medicineText = itemView.findViewById(R.id.medicineText) as? TextView
I am trying to display items in bottom navigation activity using recycler view but I am not getting the item values.
I have three layouts in my project activity_main.xml, list_row.xml and fragment_home.xml. Recycler view is in fragment_home.xml and list_row.xml contains two text views. I am not seeing any error in the code but in the log, I am getting No adapter attached message. Your help is highly appreciated.
Error:
E/RecyclerView: No adapter attached; skipping layout
Below is the HomeFragment.kt code.
class HomeFragment : Fragment() {
private var adapter:PersonListAdapter?=null
private var personList:ArrayList<Person>?=null
private var layoutManager: RecyclerView.LayoutManager?=null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
personList=ArrayList<Person>()
layoutManager= LinearLayoutManager(this.context)
adapter= PersonListAdapter(personList, this.context!!)
recyclerView.layoutManager=layoutManager
recyclerView.adapter=adapter
for (i in 0..16) {
val person = Person()
person.name="Hello" + i
person.age = 20 + i
personList!!.add(person)
}
adapter!!.notifyDataSetChanged()
}
}
MainActivity.kt code
class MainActivity : AppCompatActivity() {
private var adapter:PersonListAdapter?=null
private var personList:ArrayList<Person>?=null
private var layoutManager: RecyclerView.LayoutManager?=null
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener {item->
when(item.itemId){
R.id.home -> {
println("home pressed")
replaceFragment(HomeFragment())
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bottomNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
replaceFragment(HomeFragment())
}
private fun replaceFragment(fragment: Fragment){
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragmentContainer, fragment)
fragmentTransaction.commit()
}
}
Data Class:
class PersonListAdapter(private val list: ArrayList<Person>?, private val context: Context): RecyclerView.Adapter<PersonListAdapter.ViewHolder>()
{
override fun getItemCount(): Int {
return list!!.size
}
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
val view= LayoutInflater.from(context).inflate(R.layout.list_row,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
p0?.bindItem(list?.get(p1))
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
fun bindItem(person: Person?)
{
var name: TextView =itemView.findViewById(R.id.name) as TextView
var age: TextView =itemView.findViewById(R.id.age) as TextView
name.text=person!!.name
age.text = person.age.toString()
}
}
}
The first thing you do in your HomeFragment's onCreateView() is returning your inflated layout. So all of your code inside onCreateView method is untouchable. Instead just hold a reference to your inflated layout and return it at the end.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)
personList=ArrayList<Person>()
layoutManager= LinearLayoutManager(this.context)
adapter= PersonListAdapter(personList, this.context!!)
recyclerView.layoutManager=layoutManager
recyclerView.adapter=adapter
for (i in 0..16) {
val person = Person()
person.name="Hello" + i
person.age = 20 + i
personList!!.add(person)
}
adapter!!.notifyDataSetChanged()
return view
}
Can anyone help me to solve the problem when fragment reload data every single tab back.
This is my MainActivity
class MainActivity : AppCompatActivity() {
private fun addBottomView(){
bottomNav.setOnNavigationItemSelectedListener(object: BottomNavigationView.OnNavigationItemSelectedListener{
override fun onNavigationItemSelected(p0: MenuItem): Boolean {
var selectedItem: Fragment? = null
when(p0.itemId){
R.id.words ->
selectedItem = FragmentA.newInstance()
R.id.writing ->
selectedItem = FragmentB.newInstance()
R.id.speaking ->
selectedItem = FragmentC.newInstance()
R.id.reading ->
selectedItem = FragmentD.newInstance()
}
var ft: FragmentTransaction = supportFragmentManager.beginTransaction()
ft.replace(R.id.frame_layout, selectedItem!!)
ft.commit()
return true
}
})
var ft: FragmentTransaction = supportFragmentManager.beginTransaction()
ft.replace(R.id.frame_layout, WordsFragment.newInstance())
ft.commit()
}
}
I have found on the internet and youtube videos but no one answered this questions precisely, they recommended to use add, hide instead of replace but not so sure how to do it. if possible, can u guys explain it as clearly as you can :)
This is my ViewPageAdapter
class ViewPagerAdapter: FragmentPagerAdapter {
private val mFragmentList: MutableList<Fragment> = mutableListOf()
private val mFragmentTitleList : MutableList<String> = mutableListOf()
constructor(manager: FragmentManager) : super(manager){
}
fun addFragment(fragment: Fragment, title: String){
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getItem(position: Int): Fragment {
return mFragmentList.get(position)
}
override fun getCount(): Int {
return mFragmentList.size
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList.get(position)
}
}
Thanks
You can solve this by defining the fragments as singleton. for example:
class FragmentA: Fragment {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return super.onCreateView(inflater, container, savedInstanceState)
}
companion object {
private var instance: FragmentA? = null
fun newInstance(): FragmentA {
if (instance == null) instance = FragmentA()
return instance!!
}
}
}