Android - 底部导航标签调用的 fragment 每次都重新加载

标签 android android-fragments kotlin bottomnavigationview

我正在创建一个使用底部导航的项目。 我正在使用 fragment 进行标签调用

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
        }
    })

但 fragment 总是重新加载 我厌倦了一些方法

  1. replace().addToBackStack(null)
  2. 替换().addToBackStack(标签)
  3. 添加、隐藏、显示

addToBackStack() - 使用它,当我点击 android 默认底部后退按钮时,它弄乱了我的 fragment 布局。与 return@OnNavigationItemSelectedListener 相同 true

我关注了很多与此问题相关的论坛,但就我而言,没有任何效果。

我的第四个 fragment 是

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
    }

}
}

最佳答案

好吧,您正在提供一个新实例,每次选择一个选项时都会调用每个 fragment 的 newInstance()。您在这里有两个选择:

1) fragment 数组

在创建 fragment 时将它们保存在一个全局数组中并重复使用它

2) 标签

为 fragment 添加一个标签,稍后使用它来查找相同的 fragment 。

因为您已经设置了最适合您的标签:

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
                }
            }

编辑:

要清除 ListView ,您可以在添加新内容之前简单地清除它,因此每次调用 onCreateView 时,您的列表都会从头开始初始化:

listOfMoreMenus.clear()
listOfMoreMenus.add(MoreLinksObject("test1","link1")) 
listOfMoreMenus.add(MoreLinksObject("test2","link2")) 
listOfMoreMenus.add(MoreLinksObject("test3","link3")) 

至于更改标题,如果您的工具栏属于 Activity ,您可以在每次更改 fragment 时设置标题。(见上文)。如果它属于 fragment ,那么您需要在 onCreateView 方法中更改它,以便每次 fragment 更改时它都会更改。

关于Android - 底部导航标签调用的 fragment 每次都重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50141842/

相关文章:

android - 无法访问 fragment 内的 Textview

java - 从 fragment 返回 Activity 时调用函数

kotlin - 使用 launch 启动协程或使用 coroutineScope 启动协程之间的区别

android - 在 Android OpenGL ES 上只能看到没有几何图形的 glClear 颜色

android - getView() 和 getActivity() 有什么区别?

android - 无法解析 : com. android.support :appcompat-v7:26. 0.0

java - android 将 json 传递给 HashMap 到 alertdialog 中显示的 llistview

android - AlertDialog setOnDismissListener 不工作

android - 无法访问 'split' : it is private in file

android - 选中时如何将项目设置为 Recycler View 的中心