Reputation: 173
I am creating a project which uses bottom navigation. I am using fragment to make tabs call
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.frame_layout, Fragment1.newInstance(),Fragment1.newInstance().TAG)
transaction.addToBackStack(null).commit()
bottomNavigationView.setOnNavigationItemSelectedListener(object : BottomNavigationView.OnNavigationItemSelectedListener {
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if(item.itemId == lastSelectedItemId){
return true
}
var menuTag:String ?= null
var selectedFragment: Fragment? = null
lastSelectedItemId = item.itemId
when (item.itemId) {
R.id.tab1 -> {
selectedFragment = Fragment1.newInstance()
menuTag = selectedFragment.TAG
}
R.id.tab2 -> {
selectedFragment = Fragment2.newInstance()
menuTag = selectedFragment.TAG
}
R.id.tab3 -> {
selectedFragment = Fragment3.newInstance()
menuTag = selectedFragment.TAG
}
R.id.tab4 ->{
selectedFragment = Fragment4.newInstance()
menuTag = selectedFragment.TAG
}
}
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.frame_layout, selectedFragment,menuTag)
transaction.addToBackStack(menuTag).commit()
return true
}
})
But Fragment always reload I tired some method
addToBackStack() - using this, when i clicked android default bottom back button, its messing my layout of fragment. same with return@OnNavigationItemSelectedListener true
I followed many forum related this issue, but in my case nothing is working.
My forth fragment is
class Fragment4 : Fragment() {
var listOfMoreMenus = ArrayList<MoreLinksObject>()
var adapter: MoreLinksAdapter?=null
public var TAG: String = "more"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val moreView = inflater.inflate(R.layout.fragment_more, container, false)
val listView = moreView.findViewById(R.id.moreLinks) as ListView
listOfMoreMenus.add(MoreLinksObject("test1","link1"))
listOfMoreMenus.add(MoreLinksObject("test2","link2"))
listOfMoreMenus.add(MoreLinksObject("test3","link3"))
listView.setNestedScrollingEnabled(true)
adapter = MoreLinksAdapter(getActivity()!!,listOfMoreMenus)
listView.adapter = adapter
return moreView
}
companion object {
fun newInstance(): Fragment4 {
return Fragment4()
}
}
inner class MoreLinksAdapter: BaseAdapter {
var listOfMoreMenus= ArrayList<MoreLinksObject>()
var context: Context?=null
constructor(context:Context, listOfMoreMenus: ArrayList<MoreLinksObject>):super(){
this.listOfMoreMenus=listOfMoreMenus
this.context=context
}
override fun getItem(position: Int): Any {
return listOfMoreMenus[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return listOfMoreMenus.size
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val MoreLinkObj = listOfMoreMenus[position]
var inflator = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
var myView = inflator.inflate(R.layout.more_menu, null)
val moreMenuName = myView.findViewById(R.id.moreMenuName) as TextView
moreMenuName.text = MoreLinkObj.name!!
return myView
}
}
}
Upvotes: 3
Views: 4593
Reputation: 12007
Well, you're providing a new instance, calling newInstance()
everytime, of each fragment everytime an option is selected. You have two options here:
1) Array of fragments
Keep your fragments in a global array when they're created and just reuse it
2) Tag
Add a tag to the fragment and use it to find the same fragment later.
As you're already setting the tags that's the best for you:
val FRAGMENT_1_TAG = "FRAGMENT_1_TAG"
val FRAGMENT_2_TAG = "FRAGMENT_2_TAG"
val FRAGMENT_3_TAG = "FRAGMENT_3_TAG"
val FRAGMENT_4_TAG = "FRAGMENT_4_TAG"
when (item.itemId) {
R.id.tab1 -> {
title = "Fragment1"
selectedFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_1_TAG);
if (selectedFragment == null) {
selectedFragment = Fragment1.newInstance()
}
menuTag = FRAGMENT_1_TAG
}
R.id.tab2 -> {
title = "Fragment2"
selectedFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_2_TAG);
if (selectedFragment == null) {
selectedFragment = Fragment2.newInstance()
}
menuTag = FRAGMENT_2_TAG
}
R.id.tab3 -> {
title = "Fragment3"
selectedFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_3_TAG);
if (selectedFragment == null) {
selectedFragment = Fragment3.newInstance()
}
menuTag = FRAGMENT_3_TAG
}
R.id.tab4 ->{
title = "Fragment4"
selectedFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_4_TAG);
if (selectedFragment == null) {
selectedFragment = Fragment4.newInstance()
}
menuTag = FRAGMENT_4_TAG
}
}
EDIT:
To clear the listview you can simply clear it before adding new content, therefore everytime onCreateView is called your list will be initialized from scratch:
listOfMoreMenus.clear()
listOfMoreMenus.add(MoreLinksObject("test1","link1"))
listOfMoreMenus.add(MoreLinksObject("test2","link2"))
listOfMoreMenus.add(MoreLinksObject("test3","link3"))
As for changing the title, if your toolbar belongs to the activity you can set the title everytime you change fragments.(see above). If it belongs in the fragment then you need to change it in the onCreateView method so it will be changed everytime the fragment is changed.
Upvotes: 3