I am trying to implement a simple swiping action between the three main screens of my app (feed, forum & profile).
I've been looking for guides online but they all seem to take the same approach and show how to implement the adapter using fragments that are simple instances of a basic class that for example just inflates a title and a number on the screen.
In my case, the fragments are not all instances of the same class and are completely different.
M problem lays in the FragmentPagerAdapter. I am not sure how to return each fragment in the getItem method.
I have tried the following but it doesn't except it as a valid return statement and is still expecting one:
class PagesPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
override fun getItem(p0: Int): Fragment? {
return when (p0){
0 -> FeedFragment.newInstance()
1 -> BoardFragment.newInstance()
2 -> ProfileFragment.newInstance()
else -> FeedFragment.newInstance()
}
}
override fun getCount(): Int {
return 3
}
}
This is an example of one of my fragments:
class FeedFragment : Fragment() {
val galleryAdapter = GroupAdapter<ViewHolder>()
private fun setUpGalleryAdapter() {
feed_gallary.adapter = galleryAdapter
val galleryLayoutManager = GridLayoutManager(this.context, 3)
feed_gallary.layoutManager = galleryLayoutManager
val dummyUri =
"https://firebasestorage.googleapis.com/v0/b/dere-3d530.appspot.com/o/20150923_100950.jpg?alt=media&token=97f4b02c-75d9-4d5d-bc86-a3ffaa3a0011"
val imageUri = Uri.parse(dummyUri)
if (imageUri != null) {
galleryAdapter.add(FeedImage(imageUri))
galleryAdapter.add(FeedImage(imageUri))
galleryAdapter.add(FeedImage(imageUri))
galleryAdapter.add(FeedImage(imageUri))
galleryAdapter.add(FeedImage(imageUri))
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setUpGalleryAdapter()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
inflater.inflate(R.layout.fragment_feed, container, false)
companion object {
fun newInstance(): FeedFragment = FeedFragment()
}
}
And this is my main activity:
class MainActivity : AppCompatActivity() {
private lateinit var viewPager: ViewPager
private lateinit var pagerAdapter: PagesPagerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPager = findViewById<ViewPager>(R.id.view_pager)
pagerAdapter = PagesPagerAdapter(supportFragmentManager)
viewPager.adapter = pagerAdapter
}
}
I have also tried to define a variable currentFragment, have it reassigned for each of the when statements and have it be the return value, but as all my fragments are unique I am getting a type mismatch when trying to assign them all to one variable.
Is there some Array I can store the fragments in and then return the array position?
I feel like there is probably a simple elegant and common solution here.
Without seeing all of your code I cannot be sure but one thing to note is you must return an instance of your fragment not a reference to the class. Ex: FeedFragment() instead of FeedFragment.
Also, your when statement does not have a default case resulting in a compile error for the getItem method as you have a code path that doesn't return anything. Try the following code for getItem
override fun getItem(p0: Int): Fragment {
when(p0){
0 -> return FeedFragment.newInstance()
1 -> return BoardFragment.newInstance()
else -> return ProfileFragment.newInstance()
}
}
Unfortunately, there is no elegant solution for this case. You can store created fragment in array and then use this array when you need to access related fragment instance.
class PagesPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
private val fragments = SparseArray<WeakReference<Fragment>>()
override fun getCount() = 3
override fun getItem(position: Int): Fragment? {
val fragmentReference = fragments[position]
return if (fragmentReference?.get() != null) {
fragmentReference.get()
} else {
return when (position) {
0 -> FeedFragment.newInstance()
1 -> BoardFragment.newInstance()
2 -> ProfileFragment.newInstance()
else -> error("Incorrect position: $position")
}
}
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as Fragment
fragments.put(position, WeakReference(fragment))
return fragment
}
Related
I use view-pager2 and When I remove the first item of view-pager, It does not delete and still remains but another item removed.
For example, here I want to remove the first item of view pager but it's not be removed:
My Main Activity:
class MainActivity : AppCompatActivity() {
private lateinit var myPagerAdapter: MyPagerAdapter
private val mFragmentList: ArrayList<FragmentOne> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (mFragmentList.isEmpty()) {
mFragmentList.add(FragmentOne.newInstance(1))
mFragmentList.add(FragmentOne.newInstance(2))
mFragmentList.add(FragmentOne.newInstance(3))
}
myPagerAdapter = MyPagerAdapter(supportFragmentManager, lifecycle)
view_pager.adapter = myPagerAdapter
btn_show.setOnClickListener {
val dialog = Dialog(this)
dialog.setContentView(R.layout.fragment_dialog)
dialog.btn_remove.setOnClickListener {
//go to next item
view_pager.currentItem = 1
//remove first item
mFragmentList.removeAt(0)
//reload adapter
myPagerAdapter.notifyDataSetChanged()
}
dialog.show()
}
}
private inner class MyPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int {
return mFragmentList.size
}
override fun createFragment(position: Int): Fragment {
return mFragmentList[position]
}
}
}
FragmentOne:
class FragmentOne : Fragment() {
companion object {
fun newInstance(position: Int): FragmentOne {
val fragment = FragmentOne()
val bundle = Bundle()
bundle.putInt("id", position)
fragment.arguments = bundle
return fragment
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_one, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val id = arguments?.getInt("id")
tv?.text = id.toString()
}
}
If I don't use view-pager2, Just enough to add PagerAdapter.POSITION_NONE like this answer.
Can you help me?!
If you read the documentation it says
Note: The DiffUtil utility class relies on identifying items by ID. If you are using ViewPager2 to page through a mutable collection, you must also override getItemId() and containsItem().
Taken from this post - Migrate to ViewPager2
Since you are using a mutable ArrayList() you should also override the getItemId() method in your adapter, for the itemId you need a unique ID for every fragment, I solved it using the hashCode() function like this
override fun getItemId(position: Int): Long {
return mFragmentList[position].hashCode().toLong()
}
This should remove the first fragment and get the correct fragment from the list using the itemId
Hope this solves your problem.
Actually delete functionality is working properly 0th index fragment is deleted but after calling notfiydataset changed the first fragment gets th value as 1 and second as 2.
I did the same for java, with viewpager2 and its works!
#Override
public long getItemId(int position) {
Long longtype = Long.valueOf(mFragmentList.get(position).hashCode());
return longtype;
}
#Override
public boolean containsItem(long itemId) {
return super.containsItem(itemId);
}
I am developing a Kotlin app and at some point I want to implement viewPager to swipe between fragments. I have one activity to navigate to the rest of the app through the navigation graph. I have not really understood how this swiping should work.
My question is, do I need to implement a new activity as well besides the pageAdapter? And how this activity is going to cooperate with the main one? My app currently has a splash screen, and after that I would like to have the swipe mode between the fragments.
I want to implement viewPager to swipe between fragments.
nice
I have one activity to navigate to the rest of the app through the navigation graph.
cool
do I need to implement a new activity as well besides the pageAdapter?
no
And how this activity is going to cooperate with the main one?
don't have a second activity, then it doesn't need to "cooperate"
I would like to have the swipe mode between the fragments.
https://gist.github.com/Zhuinden/c643f03a023a9cbe83fff6c75c948d3b
class MyFragmentPagerAdapter(
private val context: Context,
fragmentManager: FragmentManager
) : FragmentPagerAdapter(fragmentManager) {
override fun getCount() = 2
override fun getItem(position: Int) = when(position) {
0 -> FirstFragment()
1 -> SecondFragment()
else -> throw IllegalStateException("Unexpected position $position")
}
override fun getPageTitle(position: Int): CharSequence = when(position) {
0 -> context.getString(R.string.first)
1 -> context.getString(R.string.second)
else -> throw IllegalStateException("Unexpected position $position")
}
}
class ParentFragment: Fragment() {
override fun onCreateView(...) = ...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewPager = view.findViewById(R.id.view_pager)
viewPager.adapter = MyFragmentPagerAdapter(requireContext(), childFragmentManager)
tabLayout.setupWithViewPager(viewPager)
}
}
Try this
in your viewPager
class pageradapter (fm: FragmentManager) : FragmentStatePagerAdapter(fm){
override fun getItem(position: Int): Fragment {
when(position){
0-> return fragment1()
1-> return fragment2() // you can add more if you have more fragments
else-> return fragment3()
}
}
override fun getCount(): Int {
return 3
number of fragments that you have so the swiping could work
}
in your fragments 1 or 2 or 3 ...etc'
class fragment1 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment1, container, false)
// write your codes
}
in your Activity after the splash screen
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main4)
val adapter = pageradapter(supportFragmentManager)
val pager = findViewById<View>(R.id.pager) as ViewPager
pager.adapter = adapter
}
i have an issue with an app that use ViewPager for display fragment. All works fine until the app goes in background and be killed from OS. It seems that after restore i have 2 IncidentScreenFragment that handle events, one with a null presenter (MVP) that crash my app.
My HomeActivity looks like:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
presenter.onViewCreated()
initViews(savedInstanceState)
}
private fun initViews(savedInstanceState: Bundle?){
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(this)
initFragment()
initMenu()
}
private fun initFragment(){
homeFragment = HomeScreenFragment.newInstance()
incidentFragment = IncidentScreenFragment.newInstance()
chatFragment = ChatFragment.newInstance()
weatherFragment = WeatherFragment.newInstance()
viewPager.adapter = ViewPagerAdapter(supportFragmentManager, this)
viewPager.offscreenPageLimit = 4
viewPager?.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {bottom_navigation.currentItem = position}
})
}
override fun getFragmentByPos(pos: Int): Fragment {
return when(pos){
0 -> homeFragment
1 -> incidentFragment
2 -> chatFragment
3 -> weatherFragment
else -> {
homeFragment
}
}
}
And my Adapter:
class ViewPagerAdapter internal constructor(fm: FragmentManager, activity:infinite_software.intelligence_center.intelligencecenter.ui.home.FragmentManager) : FragmentPagerAdapter(fm) {
private val COUNT = 4
private val activity = activity
override fun getItem(position: Int): Fragment{
var fragment: Fragment? = null
when (position) {
0 -> fragment = activity.getFragmentByPos(0)
1 -> fragment = activity.getFragmentByPos(1)
2 -> fragment = activity.getFragmentByPos(2)
3 -> fragment = activity.getFragmentByPos(3)
}
return fragment!!
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
super.destroyItem(container, position, `object`)
}
override fun getCount(): Int {
return COUNT
}
override fun getPageTitle(position: Int): CharSequence? {
return "Section " + (position + 1)
}
}
Each Fragment have a static method that return new Fragment:
companion object {
fun newInstance(): HomeScreenFragment {
return HomeScreenFragment()
}
}
When the app has been killed in background i figure out that there is 2 objects (Fragment) that listen to event, one with Presenter correctly instantiate and one without.
Below my abstract BaseFragment class:
abstract class BaseFragment<P : BasePresenter<BaseView>> : BaseView,Fragment() {
protected lateinit var presenter: P
override fun getContext(): Context {
return activity as Context
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter = instantiatePresenter()
}
override fun showError(error: String) {
(activity as BaseActivity<BasePresenter<BaseView>>).showError(error)
}
override fun showError(errorResId: Int) {
(activity as BaseActivity<BasePresenter<BaseView>>).showError(errorResId)
}
abstract fun onBackPressed(): Boolean
/**
* Instantiates the presenter the Fragment is based on.
*/
protected abstract fun instantiatePresenter(): P
abstract val TAG: String
Incident Fragment code:
class IncidentScreenFragment: BaseFragment<IncidentScreenPresenter>(), BaseView, IncidentView, AlertFilterListener, AlertItemClickListener, IncidentDetailListener {
var rvAdapter : IncidentAdapter? = null
var state : Int = LIST_STATE
override fun instantiatePresenter(): IncidentScreenPresenter {
return IncidentScreenPresenter(this)
}
override val TAG: String
get() = "INCIDENT"
override fun getContext(): Context {
return activity as Context
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_incident, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
presenter.onViewCreated()
initObserve()
}
private fun initViews(){
//Reclycler view
alertRV.layoutManager = LinearLayoutManager(context)
rvAdapter = IncidentAdapter(ArrayList(), context, this)
alertRV.adapter = rvAdapter
//Apply Listeners
headerBox.setFilterListener(this)
incidentDetailView.setListener(this)
}
override fun initObserve() {
//Init observe presenter model
val alertObserver = Observer<ArrayList<AlertModel>> { alerts ->
Timber.d("Data received from Presenter [$alerts]")
showAlertList(alerts)
}
presenter.filteredAlertList.observe(context as BaseActivity<BasePresenter<BaseView>>,alertObserver)
}
override fun updateThisFilters(boxState: Boolean, level: Int) {
presenter.updateFilterList(boxState,level)
}
fun showOnlyThisLevel(level:Int){
presenter.showOnlyThisLevel(level)
headerBox.disableBoxExcept(level)
}
fun showAlertList(list: ArrayList<AlertModel>){
rvAdapter?.updateData(list)
}
override fun onItemClick(model: AlertModel) {
presenter.loadAlertDetail(model)
}
override fun showAlertDetail(model: AlertModel) {
incidentDetailView.setUpFromModel(model)
WhiteWizard.slideLeftEffect(incidentDetailView,incidentListRootElement)
state = DETAIL_STATE
}
override fun onbackFromDetailPressed() {
WhiteWizard.slideRightEffect(incidentListRootElement,incidentDetailView)
state = LIST_STATE
}
override fun showLoader() {
loaderIncident.visibility = View.VISIBLE
}
override fun hideLoader() {
loaderIncident.visibility = View.INVISIBLE
}
override fun onBackPressed(): Boolean {
when(state){
LIST_STATE -> return false
DETAIL_STATE -> {
onbackFromDetailPressed()
return true
}
else -> return false
}
}
fun newInstance(): IncidentScreenFragment {
return IncidentScreenFragment()
}
}
When i click on the button in homePage to display fragment content i got:
Process: XXXXXX, PID: 3192
kotlin.UninitializedPropertyAccessException: lateinit property presenter has not been initialized
at infinite_software.intelligence_center.intelligencecenter.base.BaseFragment.getPresenter(BaseFragment.kt:11)
at XXXXXX.ui.home.incidentScreen.IncidentScreenFragment.showOnlyThisLevel(IncidentScreenFragment.kt:78)
at XXXXXX.ui.home.HomeActivity.filterDataWithSeverity(HomeActivity.kt:110)
at XXXXXX.ui.home.homeScreen.HomeScreenFragment.filterBy(HomeScreenFragment.kt:76)
at XXXXXX.ui.home.homeScreen.HomeScreenFragment$initViews$5.onClick(HomeScreenFragment.kt:56)
If i try to print the id of Fragment, i obtain 2 different ids from method call showOnlyThisLevel() and onBackPressed(). What i miss ?
After doing some research, it seems that the problem stems from the misnaming of FragmentPagerAdapter's method - being named getItem(), but not clearly specifying that the abstract method getItem(int position) is supposed to return a new instance of a fragment rather than just "get an instance of one".
Of course, there is not much we can do about an incorrect name after it's been out in the wild for 7 years, but at least we can fix the bug that stems from this issue in your code ;)
Without further ado, the cause of your NPE is that onCreateView (where your Presenter is instantiated) is never called.
This happens because you are creating the fragment here:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
homeFragment = HomeScreenFragment.newInstance()
incidentFragment = IncidentScreenFragment.newInstance()
}
You return this fragment from inside getItem(int position) in your FragmentPagerAdapter:
override fun getItem(position: Int): Fragment = when(position) {
...
1 -> activity.incidentFragment
...
}
So what we know about activity.incidentFragment is that in it, onCreateView() is never called.
This is caused by the fact that it's never actually added to a FragmentManager and never displayed on the screen.
That's because super.onCreate(savedInstanceState) in Activity recreates all Fragments, using their no-args constructor, via reflection, while keeping their tag (see findFragmentByTag).
So as you can see in this answer, or as I can quote here:
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
The getItem(position) method is only called if the Fragment is not found by the fragment tag that the FragmentPagerAdapter sets for the fragment, which IS automatically recreated after low memory condition kills your app.
Therefore, YOUR new fragment (that you create by hand in the Activity) is NEVER used, and therefore it has no view, never initialized, never added to FragmentManager, it's not the same instance as what's actually inside your ViewPager, and it crashes when you call it. Boom!
Solution is to instantiate the Fragment inside FragmentPagerAdapter's getItem(position) method. To get an instance of the fragment, use this answer.
I have an Activity with a ViewPager containing Fragments that are summoned with custom buttons. Currently, my custom adapter's getItem method is being called, but the pager is going blank rather than going to the new fragment
Here is my adapter :
class ScreenSlidePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
private val NUM_FRAGMENTS = 2
override fun getCount(): Int = NUM_FRAGMENTS
override fun getItem(position: Int): Fragment {
var fragment: Fragment = WelcomeFragment.newInstance()
when (position) {
0 -> fragment = WelcomeFragment.newInstance()
1 -> fragment = LanguageSelectFragment.newInstance()
}
println(position)
return fragment
}
}
Here is the method that gets called on button click. The views are given a tag corresponding to their Fragment's position in the adapter, and this is retrieved on click to pull up the right fragment.
private fun switchScreens(view: View) {
val fragment = mPagerAdapter.getItem(view.getTag().toString().toInt())
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.main_view_pager, fragment)
fragmentTransaction.commit()
}
And my fragment:
class LanguageSelectFragment : Fragment() {
private var listener: OnFragmentInteractionListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_language_select, container, false)
}
fun onButtonPressed(uri: Uri) {
listener?.onFragmentInteraction(uri)
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnFragmentInteractionListener) {
listener = context
} else {
}
}
override fun onDetach() {
super.onDetach()
listener = null
}
interface OnFragmentInteractionListener {
fun onFragmentInteraction(uri: Uri)
}
companion object {
#JvmStatic
fun newInstance() =
LanguageSelectFragment().apply {
arguments = Bundle().apply {
}
}
}
}
Do you have a ViewPager container for your framgents ?
If yes, that's not the way to use the pagerAdapter. You should see this link. It's in Java but you can easily adapt it to kotlin.
If no, I'm not sure what you are trying to do but I think the
ViewPager is what you need.
If you just want to switch fragments on a click, just use a FrameLayout to display the fragment you want and switch between them with transactions. I'm not familiar with kotlin but something like this should work.
private fun switchScreens(i: Integer) {
val fragment;
when (i) {
0 -> fragment = WelcomeFragment.newInstance()
1 -> fragment = LanguageSelectFragment.newInstance()
}
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.main_view_pager, fragment)
fragmentTransaction.commit()
}
If you want to slide to one fragment to another, you can use a ViewPager (see the link above).
Best
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.