【问题标题】:Android - Fragment called by Bottom navigation tabs is reloading every timeAndroid - 底部导航选项卡调用的片段每次都重新加载
【发布时间】:2018-05-02 19:06:58
【问题描述】:

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

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. replace().addToBackStack(tag)
  3. 添加、隐藏、显示

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

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

我的第四个片段是

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
    }

}
}

【问题讨论】:

标签: android android-fragments kotlin bottomnavigationview


【解决方案1】:

好吧,你提供了一个新实例,每次调用newInstance(),每次选择一个选项时每个片段。您有两种选择:

1) 片段数组

在创建片段时将它们保存在一个全局数组中,然后重复使用它

2) 标记

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

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

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

编辑:

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

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

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

【讨论】:

  • 选项 - 2 中的 fragmentManager 是什么?我是应用程序开发新手
  • 对不起,在你的情况下它应该支持FragmentManager
  • 是的,但是当我按下android默认的底部后退按钮时,工具栏的标题不会改变,但内容会被前一个片段替换。在 Fragment4 中,我使用列表视图,每次返回第 4 个片段时它都会增加
  • 你还在后台添加吗?我认为如果你删除它会起作用。您的列表视图在片段 4 中增加可能是因为您正在读取片段的生命周期方法之一中的项目,每次片段更改时都会调用该方法(如 oncreateview)
  • 意味着没有什么可以做,比如覆盖 fun onBackPressed() {} 并清除列表视图或其他任何内容并设置工具栏的标题 -
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 2020-06-16
  • 2020-03-23
相关资源
最近更新 更多